Skip to content

Commit

Permalink
add methods and vars
Browse files Browse the repository at this point in the history
  • Loading branch information
Filipp Makarov authored and Filipp Makarov committed Oct 15, 2024
1 parent 061b152 commit 9a08f83
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 23 deletions.
15 changes: 15 additions & 0 deletions contracts/common/BiconomySponsorshipPaymasterErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,19 @@ contract BiconomySponsorshipPaymasterErrors {
* @notice Throws when postOp gas limit is too low
*/
error PostOpGasLimitTooLow();

/**
* @notice Thrown when deposit is too low to reach minDeposit
*/
error LowDeposit();

/**
* @notice Thrown when trying to withdraw more than the balance
*/
error InsufficientFundsInGasTank();

/**
* @notice Thrown when trying to execute withdrawal request before delay has passed
*/
error RequestNotClearedYet(uint256 clearanceTime);
}
8 changes: 8 additions & 0 deletions contracts/interfaces/IBiconomySponsorshipPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { PackedUserOperation } from "account-abstraction/core/UserOperationLib.sol";

interface IBiconomySponsorshipPaymaster {

struct WithdrawalRequest {
uint256 amount;
address to;
uint256 requestSubmittedTimestamp;
}

event UnaccountedGasChanged(uint256 indexed oldValue, uint256 indexed newValue);
event FixedPriceMarkupChanged(uint256 indexed oldValue, uint256 indexed newValue);
event VerifyingSignerChanged(address indexed oldSigner, address indexed newSigner, address indexed actor);
Expand All @@ -15,6 +22,7 @@ interface IBiconomySponsorshipPaymaster {
event PriceMarkupCollected(address indexed paymasterId, uint256 indexed priceMarkup);
event Received(address indexed sender, uint256 value);
event TokensWithdrawn(address indexed token, address indexed to, uint256 indexed amount, address actor);
event WithdrawalRequestSubmitted(address withdrawAddress, uint256 amount);

function depositFor(address paymasterId) external payable;

Expand Down
50 changes: 35 additions & 15 deletions contracts/sponsorship/BiconomySponsorshipPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ contract BiconomySponsorshipPaymaster is
address public verifyingSigner;
address public feeCollector;
uint256 public unaccountedGas;
uint256 public paymasterIdWithdrawalDelay;
uint256 public minDeposit;

// Denominator to prevent precision errors when applying price markup
uint256 private constant _PRICE_DENOMINATOR = 1e6;
Expand All @@ -52,13 +54,17 @@ contract BiconomySponsorshipPaymaster is
uint256 private constant _UNACCOUNTED_GAS_LIMIT = 100_000;

mapping(address => uint256) public paymasterIdBalances;
mapping(address => bool) internal trustedPaymasterIds;
mapping (address paymasterId => WithdrawalRequest request) requests;

Check failure on line 58 in contracts/sponsorship/BiconomySponsorshipPaymaster.sol

View workflow job for this annotation

GitHub Actions / Lint sources

Explicitly mark visibility of state

constructor(
address owner,
IEntryPoint entryPointArg,
address verifyingSignerArg,
address feeCollectorArg,
uint256 unaccountedGasArg
uint256 unaccountedGasArg,
uint256 _paymasterIdWithdrawalDelay,
uint256 _minDeposit
)
BasePaymaster(owner, entryPointArg)
{
Expand All @@ -68,6 +74,8 @@ contract BiconomySponsorshipPaymaster is
}
feeCollector = feeCollectorArg;
unaccountedGas = unaccountedGasArg;
paymasterIdWithdrawalDelay = _paymasterIdWithdrawalDelay;
minDeposit = _minDeposit;
}

receive() external payable {
Expand All @@ -82,6 +90,8 @@ contract BiconomySponsorshipPaymaster is
function depositFor(address paymasterId) external payable nonReentrant {
if (paymasterId == address(0)) revert PaymasterIdCanNotBeZero();
if (msg.value == 0) revert DepositCanNotBeZero();
if(paymasterIdBalances[paymasterId] + msg.value < minDeposit)
revert LowDeposit();
paymasterIdBalances[paymasterId] += msg.value;
entryPoint.depositTo{ value: msg.value }(address(this));
emit GasDeposited(paymasterId, msg.value);
Expand Down Expand Up @@ -152,22 +162,26 @@ contract BiconomySponsorshipPaymaster is
_withdrawERC20(token, target, amount);
}

/**
* @dev Withdraws the specified amount of gas tokens from the paymaster's balance and transfers them to the
* specified address.
* @param withdrawAddress The address to which the gas tokens should be transferred.
* @param amount The amount of gas tokens to withdraw.
*/
function withdrawTo(address payable withdrawAddress, uint256 amount) external override nonReentrant {
function submitWithdrawalRequest(address withdrawAddress, uint256 amount) external {
if (withdrawAddress == address(0)) revert CanNotWithdrawToZeroAddress();
if (amount == 0) revert CanNotWithdrawZeroAmount();
uint256 currentBalance = paymasterIdBalances[msg.sender];
if (amount > currentBalance) {
revert InsufficientFunds();
}
paymasterIdBalances[msg.sender] = currentBalance - amount;
entryPoint.withdrawTo(withdrawAddress, amount);
emit GasWithdrawn(msg.sender, withdrawAddress, amount);
if (amount > currentBalance)
revert InsufficientFundsInGasTank();
requests[msg.sender] = WithdrawalRequest({amount: amount, to: withdrawAddress, requestSubmittedTimestamp: block.timestamp });
emit WithdrawalRequestSubmitted(withdrawAddress, amount);
}

function executeWithdrawalRequest(address paymasterId) external nonReentrant {
WithdrawalRequest memory req = requests[paymasterId];
uint256 clearanceTimestamp = req.requestSubmittedTimestamp + getDelay(paymasterId);
if (block.timestamp < clearanceTimestamp)
revert RequestNotClearedYet(clearanceTimestamp);
uint256 currentBalance = paymasterIdBalances[paymasterId];
if (req.amount > currentBalance)
revert InsufficientFundsInGasTank();
paymasterIdBalances[paymasterId] = currentBalance - req.amount;
entryPoint.withdrawTo(payable(req.to), req.amount);
emit GasWithdrawn(paymasterId, req.to, req.amount);
}

function withdrawEth(address payable recipient, uint256 amount) external payable onlyOwner nonReentrant {
Expand Down Expand Up @@ -380,4 +394,10 @@ contract BiconomySponsorshipPaymaster is
SafeTransferLib.safeTransfer(address(token), target, amount);
emit TokensWithdrawn(address(token), target, amount, msg.sender);
}

function getDelay(address paymasterId) internal view returns (uint256) {

Check failure on line 398 in contracts/sponsorship/BiconomySponsorshipPaymaster.sol

View workflow job for this annotation

GitHub Actions / Lint sources

Function order is incorrect, internal view function can not go after private function (line 392)
if (trustedPaymasterIds[paymasterId])
return 0;
return paymasterIdWithdrawalDelay;
}
}
22 changes: 15 additions & 7 deletions test/unit/concrete/TestSponsorshipPaymaster.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ contract TestSponsorshipPaymasterWithPriceMarkup is TestBase {
setupPaymasterTestEnvironment();
// Deploy Sponsorship Paymaster
bicoPaymaster = new BiconomySponsorshipPaymaster(
PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, PAYMASTER_FEE_COLLECTOR.addr, 7e3
{
owner: PAYMASTER_OWNER.addr,
entryPointArg: ENTRYPOINT,
verifyingSignerArg: PAYMASTER_SIGNER.addr,
feeCollectorArg: PAYMASTER_FEE_COLLECTOR.addr,
unaccountedGasArg: 7e3,
_paymasterIdWithdrawalDelay: 3600,
_minDeposit: 1e15
}
);
}

function test_Deploy() external {
BiconomySponsorshipPaymaster testArtifact = new BiconomySponsorshipPaymaster(
PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, PAYMASTER_FEE_COLLECTOR.addr, 7e3
PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, PAYMASTER_FEE_COLLECTOR.addr, 7e3, 3600, 1e15
);
assertEq(testArtifact.owner(), PAYMASTER_OWNER.addr);
assertEq(address(testArtifact.entryPoint()), ENTRYPOINT_ADDRESS);
Expand All @@ -31,33 +39,33 @@ contract TestSponsorshipPaymasterWithPriceMarkup is TestBase {
function test_RevertIf_DeployWithSignerSetToZero() external {
vm.expectRevert(abi.encodeWithSelector(VerifyingSignerCanNotBeZero.selector));
new BiconomySponsorshipPaymaster(
PAYMASTER_OWNER.addr, ENTRYPOINT, address(0), PAYMASTER_FEE_COLLECTOR.addr, 7e3
PAYMASTER_OWNER.addr, ENTRYPOINT, address(0), PAYMASTER_FEE_COLLECTOR.addr, 7e3, 3600, 1e15
);
}

function test_RevertIf_DeployWithSignerAsContract() external {
vm.expectRevert(abi.encodeWithSelector(VerifyingSignerCanNotBeContract.selector));
new BiconomySponsorshipPaymaster(
PAYMASTER_OWNER.addr, ENTRYPOINT, address(ENTRYPOINT), PAYMASTER_FEE_COLLECTOR.addr, 7e3
PAYMASTER_OWNER.addr, ENTRYPOINT, address(ENTRYPOINT), PAYMASTER_FEE_COLLECTOR.addr, 7e3, 3600, 1e15
);
}

function test_RevertIf_DeployWithFeeCollectorSetToZero() external {
vm.expectRevert(abi.encodeWithSelector(FeeCollectorCanNotBeZero.selector));
new BiconomySponsorshipPaymaster(PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, address(0), 7e3);
new BiconomySponsorshipPaymaster(PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, address(0), 7e3, 3600, 1e15);
}

function test_RevertIf_DeployWithFeeCollectorAsContract() external {
vm.expectRevert(abi.encodeWithSelector(FeeCollectorCanNotBeContract.selector));
new BiconomySponsorshipPaymaster(
PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, address(ENTRYPOINT), 7e3
PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, address(ENTRYPOINT), 7e3, 3600, 1e15
);
}

function test_RevertIf_DeployWithUnaccountedGasCostTooHigh() external {
vm.expectRevert(abi.encodeWithSelector(UnaccountedGasTooHigh.selector));
new BiconomySponsorshipPaymaster(
PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, PAYMASTER_FEE_COLLECTOR.addr, 100_001
PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, PAYMASTER_FEE_COLLECTOR.addr, 100_001, 3600, 1e15
);
}

Expand Down
10 changes: 9 additions & 1 deletion test/unit/fuzz/TestFuzz_TestSponsorshipPaymaster.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ contract TestFuzz_SponsorshipPaymasterWithPriceMarkup is TestBase {
setupPaymasterTestEnvironment();
// Deploy Sponsorship Paymaster
bicoPaymaster = new BiconomySponsorshipPaymaster(
PAYMASTER_OWNER.addr, ENTRYPOINT, PAYMASTER_SIGNER.addr, PAYMASTER_FEE_COLLECTOR.addr, 7e3
{
owner: PAYMASTER_OWNER.addr,
entryPointArg: ENTRYPOINT,
verifyingSignerArg: PAYMASTER_SIGNER.addr,
feeCollectorArg: PAYMASTER_FEE_COLLECTOR.addr,
unaccountedGasArg: 7e3,
_paymasterIdWithdrawalDelay: 3600,
_minDeposit: 1e15
}
);
}

Expand Down

0 comments on commit 9a08f83

Please sign in to comment.