Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesduncombe committed Oct 19, 2023
1 parent beb5ed5 commit d700530
Show file tree
Hide file tree
Showing 20 changed files with 337 additions and 25 deletions.
22 changes: 22 additions & 0 deletions contracts/common/AHasForwarder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "../common/lib/LibHasForwarder.sol";

import "@opengsn/contracts/src/ERC2771Recipient.sol";

/**
* @title The Forwarder Smart Contract.
* @notice The HasForwarder abstract contract is in charge of...
*/
abstract contract AHasForwarder is ERC2771Recipient {
/**
* @notice ERC2771Recipient stuff...
* FIX THE MODIFIER !!!!!!!!!!!!!!!!!!!!!!
*/
function setTrustedForwarder(address _forwarderAddress) external {
LibHasForwarder.Data storage ds = LibHasForwarder.data();
ds.forwarderAddress = _forwarderAddress;
_setTrustedForwarder(_forwarderAddress);
}
}
22 changes: 22 additions & 0 deletions contracts/common/lib/LibHasForwarder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

library LibHasForwarder {
// The current version of the storage.
uint16 internal constant STORAGE_VERSION = 1;
// This is `keccak256('HasForwarder.storage.Main')`.
bytes32 internal constant STORAGE_SLOT = 0xa9930c2ffa1b605b0243ba36b3020146bcba5a29c05a711f5ca7c705a8e851ca;

struct Data {
/// @notice The latest intializer version that was called.
uint16 version;
/// @notice This is where we store the trusted forwarder address.
address forwarderAddress;
}

function data() internal pure returns (Data storage s) {
assembly {
s.slot := STORAGE_SLOT
}
}
}
3 changes: 2 additions & 1 deletion contracts/fast/FastInitFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import "../common/lib/LibHasAutomatons.sol";
import "../common/AHasGovernors.sol";
import "../common/AHasMembers.sol";
import "../common/AHasAutomatons.sol";
import "../interfaces/IERC165.sol"; // Interface Support.
import "../interfaces/IERC173.sol"; // Ownership.
import "../interfaces/IDiamondCut.sol"; // Facet management.
import "../interfaces/IDiamondLoupe.sol"; // Facet introspection.
Expand All @@ -22,6 +21,8 @@ import "./lib/LibFastHistory.sol";
import "./lib/LibFastDistributions.sol";
import "./lib/LibFastCrowdfunds.sol";

import "@openzeppelin/contracts/interfaces/IERC165.sol";

/**
* @notice NotAlthough this contract doesn't explicitelly inherit from IERC173, ERC165, IDiamondLoupe etc, all
* methods are in fact implemented by the underlaying Diamond proxy. It is therefore safe to
Expand Down
2 changes: 2 additions & 0 deletions contracts/interfaces/ICustomErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ interface ICustomErrors {
error InconsistentParameter(string param);
error InsufficientFunds(uint256 amount);
error InternalMethod();
error InvalidApprovalDataLength();
error InvalidCrowdfundBasisPointsFee(uint32 fee);
error InvalidPaymasterDataLength();
error InvalidPhase();
error NonExistentEntry();
error OutOfBounds();
Expand Down
12 changes: 0 additions & 12 deletions contracts/interfaces/IERC165.sol

This file was deleted.

3 changes: 2 additions & 1 deletion contracts/issuer/IssuerInitFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ pragma solidity 0.8.10;

import "../common/AHasMembers.sol";
import "../common/AHasAutomatons.sol";
import "../interfaces/IERC165.sol"; // Interface Support.
import "../interfaces/IERC173.sol"; // Ownership.
import "../interfaces/IDiamondCut.sol"; // Facet management.
import "../interfaces/IDiamondLoupe.sol"; // Facet introspection.
Expand All @@ -14,6 +13,8 @@ import "./lib/AIssuerFacet.sol";
import "./lib/LibIssuer.sol";
import "./lib/LibIssuerAccess.sol";

import "@openzeppelin/contracts/interfaces/IERC165.sol";

/**
* @title The Issuer Smart Contract.
* @notice The marketplace contract is in charge of keeping track of marketplace members and has logic
Expand Down
11 changes: 10 additions & 1 deletion contracts/marketplace/MarketplaceInitFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ pragma solidity 0.8.10;

import "../common/lib/LibHasMembers.sol";
import "../common/lib/LibHasAutomatons.sol";
import "../common/lib/LibHasForwarder.sol";
import "../common/AHasMembers.sol";
import "../common/AHasAutomatons.sol";
import "../interfaces/IERC165.sol"; // Interface Support.
import "../common/AHasForwarder.sol";
import "../interfaces/IERC173.sol"; // Ownership.
import "../interfaces/IDiamondCut.sol"; // Facet management.
import "../interfaces/IDiamondLoupe.sol"; // Facet introspection.
Expand All @@ -16,12 +17,15 @@ import "./lib/LibMarketplace.sol";
import "./lib/LibMarketplaceAccess.sol";
import "./lib/LibMarketplaceTokenHolders.sol";

import "@openzeppelin/contracts/interfaces/IERC165.sol";

/// @notice The Marketplace initialization facet.
contract MarketplaceInitFacet is AMarketplaceFacet {
/// Initializers.

struct InitializerParams {
address issuer;
address trustedForwarder;
}

function initialize(InitializerParams calldata params) external onlyDeployer {
Expand Down Expand Up @@ -61,5 +65,10 @@ contract MarketplaceInitFacet is AMarketplaceFacet {

// Initialize automatons storage.
LibHasAutomatons.data().version = LibHasAutomatons.STORAGE_VERSION;

// ------------------------------------- //

// Initialize forwarder storage.
LibHasForwarder.data().forwarderAddress = params.trustedForwarder;
}
}
2 changes: 0 additions & 2 deletions contracts/marketplace/lib/LibMarketplace.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "../../lib/LibAddressSet.sol";

library LibMarketplace {
// The current version of the storage.
uint16 internal constant STORAGE_VERSION = 1;
Expand Down
40 changes: 40 additions & 0 deletions contracts/paymaster/PaymasterInitFacet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "../interfaces/IERC173.sol"; // Ownership.
import "../interfaces/IDiamondCut.sol"; // Facet management.
import "../interfaces/IDiamondLoupe.sol"; // Facet introspection.
import "../interfaces/ICustomErrors.sol";
import "../lib/LibDiamond.sol";
import "./lib/APaymasterFacet.sol";
import "./lib/LibPaymaster.sol";

import "@openzeppelin/contracts/interfaces/IERC165.sol";

/// @notice The Paymaster initialization facet.
contract PaymasterInitFacet is APaymasterFacet {
/// Initializers.

struct InitializerParams {
address marketplace;
}

function initialize(InitializerParams calldata params) external onlyDeployer {
// Make sure we haven't initialized yet.
if (LibPaymaster.data().version >= LibPaymaster.STORAGE_VERSION) revert ICustomErrors.AlreadyInitialized();

// Register interfaces.
LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
ds.supportedInterfaces[type(IERC165).interfaceId] = true;
ds.supportedInterfaces[type(IERC173).interfaceId] = true;
ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;
ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;

// ------------------------------------- //

// Initialize top-level storage.
LibPaymaster.Data storage topData = LibPaymaster.data();
topData.version = LibPaymaster.STORAGE_VERSION;
topData.marketplace = params.marketplace;
}
}
38 changes: 38 additions & 0 deletions contracts/paymaster/PaymasterTopFacet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "./lib/LibPaymaster.sol";
import "./lib/APaymasterFacet.sol";

import "@opengsn/contracts/src/BasePaymaster.sol";

contract PaymasterTopFacet is APaymasterFacet, BasePaymaster {
bool public useRejectOnRecipientRevert = false;

// TODO: Do we use the Marketplace at this point to check that the sender is allowed?
function _preRelayedCall(
GsnTypes.RelayRequest calldata relayRequest,
bytes calldata signature,
bytes calldata approvalData,
uint256 maxPossibleGas
) internal virtual override returns (bytes memory context, bool revertOnRecipientRevert) {
(signature, maxPossibleGas);
if (approvalData.length == 0) revert ICustomErrors.InvalidApprovalDataLength();
if (relayRequest.relayData.paymasterData.length == 0) revert ICustomErrors.InvalidPaymasterDataLength();

return ("", useRejectOnRecipientRevert);
}

function _postRelayedCall(
bytes calldata context,
bool success,
uint256 gasUseWithoutPost,
GsnTypes.RelayData calldata relayData
) internal virtual override {
(context, success, gasUseWithoutPost, relayData);
}

function versionPaymaster() external view virtual override returns (string memory) {
return "3.0.0-beta.3+opengsn.accepteverything.ipaymaster";
}
}
25 changes: 25 additions & 0 deletions contracts/paymaster/lib/APaymasterFacet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "../../common/AHasMembers.sol";
import "../../interfaces/ICustomErrors.sol";
import "../../lib/LibHelpers.sol";
import "../lib/LibPaymaster.sol";

/**
* @notice This contract is a group of modifiers that can be used by any Paymaster facets to guard against
* certain permissions.
*/
abstract contract APaymasterFacet {
/// Internal ACL functions.

/// ...

// Modifiers.

/// @notice Ensures that a method can only be called by the singleton deployer contract factory.
modifier onlyDeployer() virtual {
if (!LibHelpers._isDeployer(msg.sender)) revert ICustomErrors.InternalMethod();
_;
}
}
22 changes: 22 additions & 0 deletions contracts/paymaster/lib/LibPaymaster.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

library LibPaymaster {
// The current version of the storage.
uint16 internal constant STORAGE_VERSION = 1;
// This is keccak256('Paymaster.storage'):
bytes32 internal constant STORAGE_SLOT = 0x8f0e66ee30211ca069424cd4b533ee66f04c45421216c1a6601cf23359c1f7f8;

struct Data {
/// @notice The latest intializer version that was called.
uint16 version;
/// @notice The internal pointer to the Marketplace contract.
address marketplace;
}

function data() internal pure returns (Data storage s) {
assembly {
s.slot := STORAGE_SLOT
}
}
}
5 changes: 4 additions & 1 deletion deploy/20_deployMarketplace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { deployments } from "hardhat";
const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
console.log("----------------------------------- 20_deployMarketplace");

await deployMarketplace(hre, (await deployments.get("Issuer")).address);
// TODO: From a lookup...
const trustedForwarderAddr = "0xB2b5841DBeF766d4b521221732F9B618fCf34A87";

await deployMarketplace(hre, (await deployments.get("Issuer")).address, trustedForwarderAddr);
};
func.tags = ["DeployMarketplace"];
export default func;
12 changes: 12 additions & 0 deletions deploy/30_deployPaymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { deployPaymaster } from "../tasks/paymaster";
import { deployments } from "hardhat";

const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
console.log("----------------------------------- 30_deployPaymaster");

await deployPaymaster(hre, (await deployments.get("Marketplace")).address);
};
func.tags = ["DeployPaymaster"];
export default func;
19 changes: 19 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import { DEPLOYER_FACTORY_COMMON, accounts, abiFilter } from "./src/utils";
import { ISSUER_FACETS } from "./tasks/issuer";
import { MARKETPLACE_FACETS } from "./tasks/marketplace";
import { FAST_FACETS } from "./tasks/fast";
import { PAYMASTER_FACETS } from "./tasks/paymaster";

// Import all of our tasks here!
import "./tasks/accounts";
import "./tasks/issuer";
import "./tasks/marketplace";
import "./tasks/paymaster";
import "./tasks/fast";
import "./tasks/upgrades";

Expand Down Expand Up @@ -121,6 +123,23 @@ const config: HardhatUserConfig = {
...FAST_FACETS,
],
},
{
name: "Paymaster",
filter: abiFilter([
// Event types.
// ...
// Error types.
["Facet$", "InvalidApprovalDataLength()"],
["Facet$", "InvalidPaymasterDataLength()"],
]),
include: [
// "IERC165",
// "IERC173",
"IDiamondCut",
"IDiamondLoupe",
...PAYMASTER_FACETS,
],
},
],
networks: {
// Built-in for tests etc.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
},
"dependencies": {
"@openzeppelin/contracts": "^4.9.2",
"@opengsn/contracts": "^3.0.0-beta.6",
"@typechain/ethers-v5": "^11.1.1",
"@typechain/hardhat": "^9.0.0",
"ethers": "^5.7.2",
Expand Down
3 changes: 2 additions & 1 deletion scripts/geth-local-poa-chain.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ geth --dev \
--http.addr "0.0.0.0" \
--http.port 8546 \
--http.api "eth,web3,net" \
--http.corsdomain "*"
--http.corsdomain "*" \
--ipcdisable
Loading

0 comments on commit d700530

Please sign in to comment.