Skip to content

Commit

Permalink
chore(contracts): Avoid code duplication in AbstractPortal (#826)
Browse files Browse the repository at this point in the history
  • Loading branch information
alainncls authored Nov 28, 2024
1 parent f854191 commit cd6e986
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 42 deletions.
33 changes: 17 additions & 16 deletions contracts/src/abstracts/AbstractPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ abstract contract AbstractPortal is IPortal, ERC165 {
AttestationRegistry public attestationRegistry;
PortalRegistry public portalRegistry;

/// @notice Error thrown when someone else than the portal's owner is trying to revoke
/// @notice Error thrown when someone else than the portal's owner is trying to revoke or replace
error OnlyPortalOwner();

/// @notice Error thrown when withdrawing funds fails
Expand All @@ -42,14 +42,19 @@ abstract contract AbstractPortal is IPortal, ERC165 {
portalRegistry = PortalRegistry(router.getPortalRegistry());
}

/// @notice Modifier to enforce only the portal owner can perform certain actions
modifier onlyPortalOwner() {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
_;
}

/**
* @notice Withdraw funds from the Portal
* @param to the address to send the funds to
* @param amount the amount to withdraw
* @dev Only the Portal owner can withdraw funds
*/
function withdraw(address payable to, uint256 amount) external virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
function withdraw(address payable to, uint256 amount) external virtual onlyPortalOwner {
(bool s, ) = to.call{ value: amount }("");
if (!s) revert WithdrawFail();
}
Expand Down Expand Up @@ -317,15 +322,14 @@ abstract contract AbstractPortal is IPortal, ERC165 {
* @param attestationPayload the attestation payload to create attestation and register it
* @param attester the address of the attester
* @param value the value sent with the attestation
* @dev This method now uses the `onlyPortalOwner` modifier to enforce ownership rules
*/
function _onReplace(
bytes32 attestationId,
AttestationPayload memory attestationPayload,
address attester,
uint256 value
) internal virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
}
) internal virtual onlyPortalOwner {}

/**
* @notice Optional method run when attesting a batch of payloads
Expand All @@ -343,28 +347,25 @@ abstract contract AbstractPortal is IPortal, ERC165 {
* @param attestationIds the IDs of the attestations being replaced
* @param attestationsPayloads the payloads to replace
* @param validationPayloads the payloads to validate in order to replace the attestations
* @dev This method now uses the `onlyPortalOwner` modifier to enforce ownership rules
*/
function _onBulkReplace(
bytes32[] memory attestationIds,
AttestationPayload[] memory attestationsPayloads,
bytes[][] memory validationPayloads
) internal virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
}
) internal virtual onlyPortalOwner {}

/**
* @notice Optional method run when an attestation is revoked or replaced
* @notice Optional method run when an attestation is revoked
* @dev IMPORTANT NOTE: By default, revocation is only possible by the portal owner
* @dev This method now uses the `onlyPortalOwner` modifier to enforce ownership rules
*/
function _onRevoke(bytes32 /*attestationId*/) internal virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
}
function _onRevoke(bytes32 attestationId) internal virtual onlyPortalOwner {}

/**
* @notice Optional method run when a batch of attestations are revoked or replaced
* @dev IMPORTANT NOTE: By default, revocation is only possible by the portal owner
* @dev This method now uses the `onlyPortalOwner` modifier to enforce ownership rules
*/
function _onBulkRevoke(bytes32[] memory /*attestationIds*/) internal virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
}
function _onBulkRevoke(bytes32[] memory attestationIds) internal virtual onlyPortalOwner {}
}
42 changes: 19 additions & 23 deletions contracts/src/abstracts/AbstractPortalV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,21 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
portalRegistry = PortalRegistry(router.getPortalRegistry());
}

/**
* @notice Modifier to enforce only the portal owner can perform certain actions.
*/
modifier onlyPortalOwner() {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
_;
}

/**
* @notice Withdraw funds from the Portal
* @param to the address to send the funds to
* @param amount the amount to withdraw
* @dev Only the Portal owner can withdraw funds
*/
function withdraw(address payable to, uint256 amount) external virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
function withdraw(address payable to, uint256 amount) external virtual onlyPortalOwner {
(bool s, ) = to.call{ value: amount }("");
if (!s) revert WithdrawFail();
}
Expand Down Expand Up @@ -112,7 +119,7 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
bytes32 attestationId,
AttestationPayload memory attestationPayload,
bytes[] memory validationPayloads
) public payable {
) public payable onlyPortalOwner {
moduleRegistry.runModulesV2(
modules,
attestationPayload,
Expand Down Expand Up @@ -141,7 +148,7 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
bytes32[] memory attestationIds,
AttestationPayload[] memory attestationsPayloads,
bytes[][] memory validationPayloads
) public {
) public onlyPortalOwner {
moduleRegistry.bulkRunModulesV2(
modules,
attestationsPayloads,
Expand All @@ -162,7 +169,7 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
* @dev By default, revocation is only possible by the portal owner
* We strongly encourage implementing such a rule in your Portal if you intend on overriding this method
*/
function revoke(bytes32 attestationId) public {
function revoke(bytes32 attestationId) public onlyPortalOwner {
_onRevoke(attestationId);

attestationRegistry.revoke(attestationId);
Expand All @@ -172,7 +179,7 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
* @notice Bulk revokes a list of attestations for the given identifiers
* @param attestationIds the IDs of the attestations to revoke
*/
function bulkRevoke(bytes32[] memory attestationIds) public {
function bulkRevoke(bytes32[] memory attestationIds) public onlyPortalOwner {
_onBulkRevoke(attestationIds);

attestationRegistry.bulkRevoke(attestationIds);
Expand All @@ -189,7 +196,7 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
/**
* @notice Verifies that a specific interface is implemented by the Portal, following ERC-165 specification
* @param interfaceID the interface identifier checked in this call
* @return The list of modules addresses linked to the Portal
* @return True if the interface is supported, false otherwise
*/
function supportsInterface(bytes4 interfaceID) public view virtual override returns (bool) {
return
Expand All @@ -207,10 +214,7 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
}

/**
* @notice Optional method run before a payload is attested
* @param attestationPayload the attestation payload to attest
* @param validationPayloads the payloads to validate via the modules
* @param value the value sent with the attestation
* @notice Optional hooks for specific operations
*/
function _onAttest(
AttestationPayload memory attestationPayload,
Expand All @@ -231,9 +235,7 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
AttestationPayload memory attestationPayload,
address attester,
uint256 value
) internal virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
}
) internal virtual {}

/**
* @notice Optional method run when attesting a batch of payloads
Expand All @@ -256,23 +258,17 @@ abstract contract AbstractPortalV2 is IPortal, ERC165 {
bytes32[] memory attestationIds,
AttestationPayload[] memory attestationsPayloads,
bytes[][] memory validationPayloads
) internal virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
}
) internal virtual {}

/**
* @notice Optional method run when an attestation is revoked or replaced
* @dev IMPORTANT NOTE: By default, revocation is only possible by the portal owner
*/
function _onRevoke(bytes32 /*attestationId*/) internal virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
}
function _onRevoke(bytes32 /*attestationId*/) internal virtual {}

/**
* @notice Optional method run when a batch of attestations are revoked or replaced
* @dev IMPORTANT NOTE: By default, revocation is only possible by the portal owner
*/
function _onBulkRevoke(bytes32[] memory /*attestationIds*/) internal virtual {
if (msg.sender != portalRegistry.getPortalByAddress(address(this)).ownerAddress) revert OnlyPortalOwner();
}
function _onBulkRevoke(bytes32[] memory /*attestationIds*/) internal virtual {}
}
3 changes: 0 additions & 3 deletions contracts/src/examples/portals/EASPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ contract EASPortal is AbstractPortalV2 {
*/
constructor(address[] memory modules, address router) AbstractPortalV2(modules, router) {}

/// @inheritdoc AbstractPortalV2
function withdraw(address payable to, uint256 amount) external override {}

/**
* @notice Issues a Verax attestation based on an EAS attestation
* @param attestationRequest the EAS payload to attest
Expand Down
7 changes: 7 additions & 0 deletions contracts/test/examples/portals/EASPortal.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { Router } from "../../../src/Router.sol";
import { AbstractPortalV2 } from "../../../src/abstracts/AbstractPortalV2.sol";
import { AttestationRegistryMock } from "../../mocks/AttestationRegistryMock.sol";
import { ModuleRegistryMock } from "../../mocks/ModuleRegistryMock.sol";
import { PortalRegistryMock } from "../../mocks/PortalRegistryMock.sol";
import { ERC165Upgradeable } from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";

contract EASPortalTest is Test {
address public attester = makeAddr("attester");
EASPortal public easPortal;
address[] public modules = new address[](0);
ModuleRegistryMock public moduleRegistryMock = new ModuleRegistryMock();
PortalRegistryMock public portalRegistryMock = new PortalRegistryMock();
AttestationRegistryMock public attestationRegistryMock = new AttestationRegistryMock();
Router public router = new Router();

Expand All @@ -24,9 +26,12 @@ contract EASPortalTest is Test {
function setUp() public {
router.initialize();
router.updateModuleRegistry(address(moduleRegistryMock));
router.updatePortalRegistry(address(portalRegistryMock));
router.updateAttestationRegistry(address(attestationRegistryMock));

easPortal = new EASPortal(modules, address(router));

portalRegistryMock.register(address(easPortal), "EASPortal", "EASPortal description", false, "EAS");
}

function test_attest() public {
Expand Down Expand Up @@ -134,6 +139,7 @@ contract EASPortalTest is Test {

function test_revoke() public {
vm.expectRevert(EASPortal.NoRevocation.selector);
vm.prank(address(this));
easPortal.revoke(bytes32(uint256(1)));
}

Expand All @@ -147,6 +153,7 @@ contract EASPortalTest is Test {
replacingAttestations[1] = bytes32(uint256(3));

vm.expectRevert(EASPortal.NoBulkRevocation.selector);
vm.prank(address(this));
easPortal.bulkRevoke(attestationsToRevoke);
}

Expand Down

0 comments on commit cd6e986

Please sign in to comment.