Skip to content

Commit

Permalink
final script for paymaster
Browse files Browse the repository at this point in the history
  • Loading branch information
ABD-AZE committed Oct 20, 2024
1 parent 6d84725 commit 555795e
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 97 deletions.
2 changes: 1 addition & 1 deletion cache/solidity-files-cache.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion out/ZapAccount.sol/ZapAccount.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion out/ZapAccountFactory.sol/ZapAccountFactory.json

Large diffs are not rendered by default.

149 changes: 96 additions & 53 deletions script/ZapExecute.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ import {EntryPoint, PackedUserOperation} from "../lib/account-abstraction/contra
import {DevOpsTools} from "../lib/foundry-devops/src/DevOpsTools.sol";
import {MessageHashUtils} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol";
import "../src/ZapAccount.sol";
import {console} from "../lib/forge-std/src/console.sol";
import "../lib/forge-std/src/console.sol";
import "../src/ZapAccount.sol";
contract Deploy is Script {
// change salt at 2 places
//anvil
// address AF = 0x90193C961A926261B756D1E5bb255e67ff9498A1;
// address EP = 0x34A1D3fff3958843C43aD80F30b94c510645C316;
// address EP = 0x34A1D3fff3958843C43aD80F30b94c510645C316;
// base sepolia
address public AF = 0x732DC53Ed45d08c716758bAcFCe660BE7641A35C;
address public EP = 0x0000000071727De22E5E9d8BAf0edAc6f37da032 ;
address public PM = 0x9af33f4a0e980272d98b65e655227c57d43f6c0c;
address public EP = 0x0000000071727De22E5E9d8BAf0edAc6f37da032;
address public PM = 0x1B3c85D5257fA52A4F72Fe31Cb9c26bDFF13F998;
//base sepolia
uint256 salt = 13579111512;
uint256 salt = 13579111512;
address myaddress = 0x509d5DC4d295a7F534eC58F0f75Fd723ab72F8D4;
//anvil
// address myaddress = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
Expand All @@ -42,54 +42,65 @@ contract Deploy is Script {
EntryPoint ep = EntryPoint(payable(EP));

function run() external {
// 1000000
uint128 verificationGasLimit = 1000000; // Typical gas limit for a simple transaction
uint128 callGasLimit = 100000; // Adjusted gas limit for contract execution
uint128 maxPriorityFeePerGas = 619488; // 2 Gwei
uint128 maxFeePerGas = 619488; // 50 Gwei
address sender = getAddress(myaddress, salt); //vm.computeCreateAddress(AF, 1);
console.log(sender);
bytes memory Calldata = generateCallData(address(0x9f13c3FA4eAE22A984c1f9c4936477C448540A22), 0, hex"");

// console.log(sender);
bytes memory Calldata = generateCallData(
address(0x9f13c3FA4eAE22A984c1f9c4936477C448540A22),
0,
hex""
);
uint48 validUntil = uint48(block.timestamp + 1000);
uint48 validAfter = uint48(block.timestamp);
// bytes memory Calldata = generateCallData(address(0x9f13c3FA4eAE22A984c1f9c4936477C448540A22), 0.1 ether, hex"");
bytes memory ic = generateInitCode(AF, myaddress, salt);
PackedUserOperation memory userOp= PackedUserOperation({
bytes memory ic = generateInitCode(AF, myaddress, salt);
bytes memory PMData = abi.encodePacked(PM,verificationGasLimit,verificationGasLimit);
//console.log(PMData);
PackedUserOperation memory userOp = PackedUserOperation({
sender: sender,
nonce: ep.getNonce(sender,0),
initCode: ic,
nonce: ep.getNonce(sender, 0),
initCode: hex"",
callData: Calldata,
accountGasLimits: bytes32(uint256(verificationGasLimit) << 128 | callGasLimit),
preVerificationGas: uint256(1109448),
gasFees: bytes32(uint256(maxPriorityFeePerGas) << 128 | maxFeePerGas),
paymasterAndData: hex"",
accountGasLimits: bytes32(
(uint256(verificationGasLimit) << 128) | callGasLimit
),
preVerificationGas: uint256(verificationGasLimit),
gasFees: bytes32(
(uint256(maxPriorityFeePerGas) << 128) | maxFeePerGas
),
paymasterAndData: PMData,
signature: hex""
});
bytes memory PMData = GeneratePaymasterAndData(userOp,validUntil , validAfter);
userOp.paymasterAndData = PMData;
// paymaster data: first 20bytes are paymaster address, next 32 bytes
// paymaster data: first 20bytes are paymaster address, next 32 bytes
// PMData = GenerateSignedPMData(userOp, validUntil, validAfter);
// // console.log(PMData);
// userOp.paymasterAndData = PMData;
bytes32 userOpHash = ep.getUserOpHash(userOp);
// bytes32 userOpHash = hex"";

bytes32 digest = MessageHashUtils.toEthSignedMessageHash(userOpHash);
uint8 v;
bytes32 r;
bytes32 s;
uint256 BASE_SEPOLIA_DEFAULT_KEY = 0x9442ed40cedff46250c0d84d2f0ae177c08ffb4dfe8cf78a1f5b6e999aa18d44;
uint256 ANVIL_DEFAULT_KEY = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80;
// (v, r, s) = vm.sign(BASE_SEPOLIA_DEFAULT_KEY, digest);
(v,r,s) = vm.sign(BASE_SEPOLIA_DEFAULT_KEY, digest);
(v, r, s) = vm.sign(BASE_SEPOLIA_DEFAULT_KEY, digest);
bytes memory sig = abi.encodePacked(r, s, v);
userOp.signature = sig;
PackedUserOperation[] memory ops = new PackedUserOperation[](1);
ops[0] = userOp;
uint256 gasLimit = 2000000; // Adjust this value as needed
vm.startBroadcast();
// (bool success, ) = address(sender).call{value: 0.5 ether}("");
ep.depositTo{value: 0.1 ether}(PM);
ep.depositTo{value: .05 ether}(PM);
// require(success, "Transfer failed");
ep.handleOps{gas:gasLimit}(
ops,
payable(myaddress)
);
ep.handleOps{gas: gasLimit}(ops, payable(myaddress));
vm.stopBroadcast();
}
function getAddress(
Expand All @@ -102,12 +113,7 @@ contract Deploy is Script {
abi.encode(owner)
);
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff),
AF,
byteSalt,
keccak256(bytecode)
)
abi.encodePacked(bytes1(0xff), AF, byteSalt, keccak256(bytecode))
);
return address(uint160(uint256(hash)));
}
Expand All @@ -131,42 +137,79 @@ contract Deploy is Script {
bytes memory data
) public pure returns (bytes memory) {
return
abi.encodeWithSelector(ZapAccount.execute.selector, dest,value,data);
abi.encodeWithSelector(
ZapAccount.execute.selector,
dest,
value,
data
);
}
function GeneratePaymasterAndData(PackedUserOperation memory userOp, uint48 validUntil, uint48 validAfter) public view returns (bytes memory) {
bytes32 digest = MessageHashUtils.toEthSignedMessageHash(getHash(userOp, validUntil, validAfter));
function GenerateUnsignedPMData(
uint48 validUntil,
uint48 validAfter
) public view returns (bytes memory) {
bytes memory paymasterAndData = abi.encodePacked(
address(PM),
abi.encode(validUntil, validAfter)
);
return paymasterAndData;
}
function GenerateSignedPMData(
PackedUserOperation memory userOp,
uint48 validUntil,
uint48 validAfter
) public view returns (bytes memory) {
bytes32 digest = MessageHashUtils.toEthSignedMessageHash(
getHash(userOp, validUntil, validAfter)
);
uint8 v;
bytes32 r;
bytes32 s;
uint256 BASE_SEPOLIA_DEFAULT_KEY = 0x9442ed40cedff46250c0d84d2f0ae177c08ffb4dfe8cf78a1f5b6e999aa18d44;
(v,r,s) = vm.sign(BASE_SEPOLIA_DEFAULT_KEY, digest);
(v, r, s) = vm.sign(BASE_SEPOLIA_DEFAULT_KEY, digest);
bytes memory sig = abi.encodePacked(r, s, v);
bytes memory paymasterAndData = abi.encodePacked(
address(PM),
abi.encode(validUntil, validAfter),
sig
);
return paymasterAndData;
}
function getHash(PackedUserOperation calldata userOp, uint48 validUntil, uint48 validAfter)
public view returns (bytes32) {
function getHash(
PackedUserOperation memory userOp,
uint48 validUntil,
uint48 validAfter
) public view returns (bytes32) {
//can't use userOp.hash(), since it contains also the paymasterAndData itself.
address sender = userOp.getSender();
uint256 extractedValue = uint256(
extractBytes20(userOp.paymasterAndData, 20)
);

return
keccak256(
abi.encode(
sender,
userOp.nonce,
keccak256(userOp.initCode),
keccak256(userOp.callData),
userOp.accountGasLimits,
uint256(bytes32(userOp.paymasterAndData[20 : 52])),
userOp.preVerificationGas,
userOp.gasFees,
block.chainid,
address(this),
validUntil,
validAfter
)
);
abi.encode(
userOp.sender,
userOp.nonce,
keccak256(userOp.initCode),
keccak256(userOp.callData),
userOp.accountGasLimits,
extractedValue,
userOp.preVerificationGas,
userOp.gasFees,
block.chainid,
PM,
validUntil,
validAfter
)
);
}
function extractBytes20(
bytes memory data,
uint256 start
) internal pure returns (bytes32 result) {
require(data.length >= start + 32, "Insufficient data length");
assembly {
result := mload(add(data, add(0x20, start)))
}
}
}
}
2 changes: 1 addition & 1 deletion script/ZapPaymaster.s.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pragma solidity ^0.8.9;

import {Script} from "../lib/forge-std/src/Script.sol";
import "../src/ZapPaymaster.sol";
import {ZapPayMaster} from "../src/ZapPaymasterTemp.sol";

contract DeployPaymaster is Script{
address public EP = 0x0000000071727De22E5E9d8BAf0edAc6f37da032;
Expand Down
80 changes: 40 additions & 40 deletions src/UserManager.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// // SPDX-License-Identifier: MIT
// pragma solidity ^0.8.20;

import {Nonces} from "../lib/openzeppelin-contracts/contracts/utils/Nonces.sol";
import {ECDSA} from "../lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol";
Expand All @@ -24,12 +24,12 @@ contract UserManager is Nonces, VRFConsumerBaseV2 {
address public immutable i_ServerManager;
VRFCoordinatorV2Interface COORDINATOR;

uint64 s_subscriptionId;
address vrfCoordinator;
bytes32 keyHash;
uint32 callbackGasLimit = 100000;
uint16 requestConfirmations = 3;
uint32 numWords = 1;
// uint64 s_subscriptionId;
// // address vrfCoordinator;
// bytes32 keyHash;
// uint32 callbackGasLimit = 100000;
// uint16 requestConfirmations = 3;
// uint32 numWords = 1;

mapping(uint256 => address) public requestIdToUser;
mapping(uint256 => AdType) public requestIdToAdType;
Expand All @@ -47,8 +47,8 @@ contract UserManager is Nonces, VRFConsumerBaseV2 {
event AdClicked(uint256 indexed adId, address indexed user);
event WeightsUpdated(uint256 priceWeight, uint256 viewsWeight, uint256 freshnessWeight, uint256 performanceWeight);

enum AdType { Video, Banner }
enum AdStatus { Active, Inactive }
// enum AdType { Video, Banner }
// enum AdStatus { Active, Inactive }

struct Ad {
uint256 id;
Expand All @@ -73,25 +73,25 @@ contract UserManager is Nonces, VRFConsumerBaseV2 {
uint256 lastAdView; // Last block number when user viewed an ad
}

mapping(address => User) public users;

constructor(
address _serverManager,
address _vrfCoordinator,
bytes32 _keyHash,
uint64 _subscriptionId
) VRFConsumerBaseV2(_vrfCoordinator) {
i_ServerManager = _serverManager;
vrfCoordinator = _vrfCoordinator;
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
keyHash = _keyHash;
s_subscriptionId = _subscriptionId;
}

modifier OnlyServer() {
require(msg.sender == i_ServerManager, "Only server can call this function");
_;
}
// mapping(address => User) public users;

// constructor(
// address _serverManager,
// address _vrfCoordinator,
// bytes32 _keyHash,
// uint64 _subscriptionId
// ) VRFConsumerBaseV2(_vrfCoordinator) {
// i_ServerManager = _serverManager;
// vrfCoordinator = _vrfCoordinator;
// COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
// keyHash = _keyHash;
// s_subscriptionId = _subscriptionId;
// }

// modifier OnlyServer() {
// require(msg.sender == i_ServerManager, "Only server can call this function");
// _;
// }

// Enhanced ad selection logic
function calculateAdWeight(uint256 adId) public view returns (uint256) {
Expand Down Expand Up @@ -274,17 +274,17 @@ contract UserManager is Nonces, VRFConsumerBaseV2 {
_useNonce(msg.sender);
}

function viewBannerAd(uint256 adId) public OnlyServer {
require(_allowAdView(adId), "Ad not available");
users[msg.sender].bannerAdsViewed++;
}

function verifyAdView(address user, uint256 adId, uint256 _nonce, bool clicked, bytes memory signature) public view returns (bool, bool) {
require(nonces(user) == _nonce + 1, "Invalid nonce");
bytes32 message = keccak256(abi.encodePacked(user, adId, _nonce, clicked));
address signer = ECDSA.recover(message, signature);
return (signer == i_ServerManager, clicked);
}
// function viewBannerAd(uint256 adId) public OnlyServer {
// require(_allowAdView(adId), "Ad not available");
// users[msg.sender].bannerAdsViewed++;
// }

// function verifyAdView(address user, uint256 adId, uint256 _nonce, bool clicked, bytes memory signature) public view returns (bool, bool) {
// require(nonces(user) == _nonce + 1, "Invalid nonce");
// bytes32 message = keccak256(abi.encodePacked(user, adId, _nonce, clicked));
// address signer = ECDSA.recover(message, signature);
// return (signer == i_ServerManager, clicked);
// }

// Utility functions
function getAd(uint256 adId) public view returns (Ad memory) {
Expand Down
Loading

0 comments on commit 555795e

Please sign in to comment.