-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
289 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import "account-abstraction/core/BasePaymaster.sol"; | ||
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; | ||
import {CABPaymaster} from "./CABPaymaster.sol"; | ||
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; | ||
import {IInvoiceManager} from "../interfaces/IInvoiceManager.sol"; | ||
import {ICrossL2Prover} from "@vibc-core-smart-contracts/contracts/interfaces/ICrossL2Prover.sol"; | ||
|
||
contract CABPaymasterFactory is Ownable { | ||
address public invoiceManager; | ||
address public crossL2Prover; | ||
address public verifyingSigner; | ||
|
||
event CABPaymasterCreated(address indexed owner, address indexed cabPaymaster); | ||
|
||
event InvoiceManagerUpdated(address indexed newInvoiceManager); | ||
event CrossL2ProverUpdated(address indexed newCrossL2Prover); | ||
event VerifyingSignerUpdated(address indexed newVerifyingSigner); | ||
|
||
constructor(address _owner, address _crossL2Prover, address _invoiceManager, address _verifyingSigner) | ||
Ownable(_owner) | ||
{ | ||
crossL2Prover = _crossL2Prover; | ||
invoiceManager = _invoiceManager; | ||
verifyingSigner = _verifyingSigner; | ||
} | ||
|
||
/* | ||
* @notice Create a CABPaymaster with the given _owner and _salt. | ||
* @param _owner The owner of the CABPaymaster. | ||
* @param _nonce The nonce for the CABPaymaster. | ||
* @return cabPaymaster The address of the CABPaymaster. | ||
*/ | ||
function createCABPaymaster(address _owner, bytes32 _nonce, address[] memory _supportedTokens) | ||
external | ||
returns (address cabPaymaster) | ||
{ | ||
bytes32 salt = keccak256(abi.encode(_owner, _nonce)); | ||
require(_owner != owner(), "CABPaymasterFactory: Wrong owner"); | ||
cabPaymaster = getAddressWithNonce(_owner, _nonce); | ||
if (cabPaymaster.code.length > 0) return cabPaymaster; | ||
cabPaymaster = address( | ||
new CABPaymaster{salt: salt}( | ||
ICrossL2Prover(crossL2Prover), IInvoiceManager(invoiceManager), verifyingSigner, _owner | ||
) | ||
); | ||
|
||
CABPaymaster(payable(cabPaymaster)).initialize(_supportedTokens); | ||
emit CABPaymasterCreated(_owner, cabPaymaster); | ||
} | ||
|
||
/* | ||
* @notice Return the address of a CABPaymaster that would be deployed with the given _salt. | ||
*/ | ||
function getAddressWithNonce(address _owner, bytes32 _nonce) public view returns (address) { | ||
bytes32 salt = keccak256(abi.encode(_owner, _nonce)); | ||
return Create2.computeAddress( | ||
salt, | ||
keccak256( | ||
abi.encodePacked( | ||
type(CABPaymaster).creationCode, abi.encode(crossL2Prover, invoiceManager, verifyingSigner, _owner) | ||
) | ||
) | ||
); | ||
} | ||
|
||
/* | ||
* @notice Update the invoice manager. | ||
* @param _invoiceManager The new invoice manager. | ||
*/ | ||
function updateInvoiceManager(address _invoiceManager) public onlyOwner { | ||
require(_invoiceManager != address(0), "Invoice manager cannot be the zero address"); | ||
invoiceManager = _invoiceManager; | ||
emit InvoiceManagerUpdated(_invoiceManager); | ||
} | ||
|
||
/* | ||
* @notice Update the cross-chain prover. | ||
* @param _crossL2Prover The new cross-chain prover. | ||
*/ | ||
function updateCrossL2Prover(address _crossL2Prover) public onlyOwner { | ||
require(_crossL2Prover != address(0), "Cross-chain prover cannot be the zero address"); | ||
crossL2Prover = _crossL2Prover; | ||
emit CrossL2ProverUpdated(_crossL2Prover); | ||
} | ||
|
||
/* | ||
* @notice Update the verifying signer. | ||
* @param _verifyingSigner The new verifying signer. | ||
*/ | ||
function updateVerifyingSigner(address _verifyingSigner) public onlyOwner { | ||
require(_verifyingSigner != address(0), "Verifying signer cannot be the zero address"); | ||
verifyingSigner = _verifyingSigner; | ||
emit VerifyingSignerUpdated(_verifyingSigner); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import "@openzeppelin/contracts/access/Ownable.sol"; | ||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
|
||
library LibTokens { | ||
address public constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; | ||
|
||
event SupportedTokenAdded(address token); | ||
event SupportedTokenRemoved(address token); | ||
|
||
struct TokensStore { | ||
address[] tokens; | ||
mapping(address => bool) supported; | ||
} | ||
|
||
function addSupportedToken(TokensStore storage store, address token) public { | ||
require(!store.supported[token], "TokenManager: token already supported"); | ||
store.supported[token] = true; | ||
store.tokens.push(token); | ||
} | ||
|
||
function removeSupportedToken(TokensStore storage store, address token) public { | ||
if (token == NATIVE_TOKEN) { | ||
require(address(this).balance == 0, "TokenManager: native token has balance"); | ||
} else { | ||
uint256 balance = IERC20(token).balanceOf(address(this)); | ||
require(balance == 0, "TokenManager: token has balance"); | ||
} | ||
|
||
uint256 length = store.tokens.length; | ||
for (uint256 i = 0; i < length;) { | ||
if (store.tokens[i] == token) { | ||
store.supported[token] = false; | ||
store.tokens[i] = store.tokens[length - 1]; | ||
store.tokens.pop(); | ||
break; | ||
} | ||
unchecked { | ||
i++; | ||
} | ||
} | ||
} | ||
|
||
function getSupportedTokens(TokensStore storage store) public view returns (address[] memory) { | ||
return store.tokens; | ||
} | ||
} |
Oops, something went wrong.