Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: generate Markdown table with interface IDs #620

Merged
merged 6 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/LSP0ERC725Account/ILSP0ERC725Account.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {ILSP1UniversalReceiver} from "../LSP1UniversalReceiver/ILSP1UniversalRec
import {ILSP14Ownable2Step} from "../LSP14Ownable2Step/ILSP14Ownable2Step.sol";

/**
* @title The Interface of LSP0-ERC725Account Standard
* @title Interface of the LSP0 - ERC725Account standard, an account based smart contract that represents an identity on-chain.
* https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-0-ERC725Account.md
*
* @author Fabian Vogelsteller <fabian@lukso.network>, Jean Cavallera (CJ42)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.0;

/**
* @title interface of the LSP11 - Basic Social Recovery standard
* @title Interface of the LSP11 - Basic Social Recovery standard, a contract to recover access control into an account.
* @dev Sets permission for a controller address after a recovery process to interact with an ERC725
* contract via the LSP6KeyManager
*/
Expand Down
3 changes: 1 addition & 2 deletions contracts/LSP14Ownable2Step/ILSP14Ownable2Step.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
pragma solidity ^0.8.4;

/**
* @dev Extended version of Ownable (EIP173) in which, transferring or renouncing ownership
* of the contract works in 2 steps.
* @title Interface of the LSP14 - Ownable 2-step standard, an extension of the EIP173 (Ownable) standard with 2-step process to transfer or renounce ownership.
*/
interface ILSP14Ownable2Step {
/**
Expand Down
6 changes: 4 additions & 2 deletions contracts/LSP17ContractExtension/LSP17Extendable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import {_INTERFACEID_LSP17_EXTENDABLE} from "./LSP17Constants.sol";
import "./LSP17Errors.sol";

/**
* @title Implementation of the fallback logic according to LSP17ContractExtension
* @dev Module to be inherited used to extend the functionality of the parent contract when
* @title Module to add more functionalities to a contract using extensions.
*
* @dev Implementation of the `fallback(...)` logic according to LSP17 - Contract Extension standard.
* This module can be inherited to extend the functionality of the parent contract when
* calling a function that doesn't exist on the parent contract via forwarding the call
* to an extension mapped to the function selector being called, set originally by the parent contract
*/
Expand Down
6 changes: 4 additions & 2 deletions contracts/LSP17ContractExtension/LSP17Extension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {_INTERFACEID_LSP17_EXTENSION} from "./LSP17Constants.sol";

/**
* @title Implementation of the extension logic according to LSP17ContractExtension
* @dev To be inherited to provide context of the msg variable related to the extendable contract
* @title Module to create a contract that can act as an extension.
*
* @dev Implementation of the extension logic according to LSP17ContractExtension.
* This module can be inherited to provide context of the msg variable related to the extendable contract
*/
abstract contract LSP17Extension is ERC165 {
/**
Expand Down
2 changes: 1 addition & 1 deletion contracts/LSP1UniversalReceiver/ILSP1UniversalReceiver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.4;

/**
* @title The interface for LSP1UniversalReceiver
* @title Interface of the LSP1 - Universal Receiver standard, an entry function for a contract to receive arbitrary information.
* @dev LSP1UniversalReceiver allows to receive arbitrary messages and to be informed when assets are sent or received
*/
interface ILSP1UniversalReceiver {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
pragma solidity ^0.8.4;

/**
* @title Interface for the LSP20 Call Verification standard, a set of functions intended to perform verifications on behalf of another contract.
*
* @dev Interface to be inherited for contract supporting LSP20-CallVerification
*/
interface ILSP20CallVerification {
interface ILSP20CallVerifier {
/**
* @return magicValue MUST return the first 3 bytes of `lsp20VerifyCall(address,uint256,bytes)` function selector if the call to
* the function is allowed, concatened with a byte that determines if the lsp20VerifyCallResult function should
Expand Down
5 changes: 3 additions & 2 deletions contracts/LSP20CallVerification/LSP20CallVerification.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ pragma solidity ^0.8.4;

// interfaces

import {ILSP20CallVerification as ILSP20} from "./ILSP20CallVerification.sol";
import {ILSP20CallVerifier as ILSP20} from "./ILSP20CallVerifier.sol";

// errors
import "./LSP20Errors.sol";

/**
* @title Implementation of contract calling the verification functions according to LSP20CallVerification
* @title Implementation of a contract calling the verification functions according to LSP20 - Call Verification standard.
*
* @dev Module to be inherited used to verify the execution of functions according to a verifier address.
* Verification can happen before or after execution based on a magicValue.
*/
Expand Down
2 changes: 1 addition & 1 deletion contracts/LSP6KeyManager/ILSP6KeyManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pragma solidity ^0.8.4;
import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";

/**
* @dev Contract acting as a controller of an ERC725 Account, using permissions stored in the ERC725Y storage
* @title Interface of the LSP6 - Key Manager standard, a contract acting as a controller of an ERC725 Account using predfined permissions.
*/
interface ILSP6KeyManager is
IERC1271
Expand Down
4 changes: 1 addition & 3 deletions contracts/LSP6KeyManager/LSP6KeyManagerCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ pragma solidity ^0.8.5;
// interfaces
import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import {ILSP6KeyManager} from "./ILSP6KeyManager.sol";
import {
ILSP20CallVerification as ILSP20
} from "../LSP20CallVerification/ILSP20CallVerification.sol";
import {ILSP20CallVerifier as ILSP20} from "../LSP20CallVerification/ILSP20CallVerifier.sol";

// modules
import {ILSP14Ownable2Step} from "../LSP14Ownable2Step/ILSP14Ownable2Step.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {IERC725Y} from "@erc725/smart-contracts/contracts/interfaces/IERC725Y.sol";

/**
* @title interface of the LSP7 - Digital Asset standard.
* @title Interface of the LSP7 - Digital Asset standard, a fungible digital asset.
*/
interface ILSP7DigitalAsset is IERC165, IERC725Y {
// --- Events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {IERC725Y} from "@erc725/smart-contracts/contracts/interfaces/IERC725Y.sol";

/**
* @title interface of the LSP8 - Identifiable Digital Asset standard.
* @title Interface of the LSP8 - Identifiable Digital Asset standard, a non-fungible digital asset.
*/
interface ILSP8IdentifiableDigitalAsset is IERC165, IERC725Y {
// --- Events
Expand Down
2 changes: 1 addition & 1 deletion contracts/LSP9Vault/ILSP9Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {ILSP1UniversalReceiver} from "../LSP1UniversalReceiver/ILSP1UniversalRec
import {ILSP14Ownable2Step} from "../LSP14Ownable2Step/ILSP14Ownable2Step.sol";

/**
* @title Interface of LSP9Vault built on top of ERC725, LSP1UniversalReceiver
* @title Interface of LSP9 - Vault standard, a blockchain vault that can hold assets and interact with other smart contracts.
* @dev this interface implicitly inherits: IERC165, IERC725X, IERC725Y, ILSP1UniversalReceiver, ILSP14Ownable2Step
*/
interface ILSP9Vault {
Expand Down
4 changes: 1 addition & 3 deletions contracts/Mocks/ERC165Interfaces.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ import {
ILSP11BasicSocialRecovery as ILSP11
} from "../LSP11BasicSocialRecovery/ILSP11BasicSocialRecovery.sol";
import {ILSP14Ownable2Step as ILSP14} from "../LSP14Ownable2Step/ILSP14Ownable2Step.sol";
import {
ILSP20CallVerification as ILSP20
} from "../LSP20CallVerification/ILSP20CallVerification.sol";
import {ILSP20CallVerifier as ILSP20} from "../LSP20CallVerification/ILSP20CallVerifier.sol";

// constants
import {_INTERFACEID_LSP0} from "../LSP0ERC725Account/LSP0Constants.sol";
Expand Down
4 changes: 2 additions & 2 deletions contracts/Mocks/LSP20Owners/FallbackReturnMagicValue.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;

import {ILSP20CallVerification} from "../../LSP20CallVerification/ILSP20CallVerification.sol";
import {ILSP20CallVerifier} from "../../LSP20CallVerification/ILSP20CallVerifier.sol";
import {ILSP14Ownable2Step} from "../../LSP14Ownable2Step/ILSP14Ownable2Step.sol";

/**
Expand All @@ -16,7 +16,7 @@ contract FallbackReturnMagicValue {
// solhint-disable no-complex-fallback
fallback(bytes calldata) external returns (bytes memory) {
emit FallbackCalled(msg.data);
return bytes.concat(ILSP20CallVerification.lsp20VerifyCall.selector, bytes28(0));
return bytes.concat(ILSP20CallVerifier.lsp20VerifyCall.selector, bytes28(0));
}

function acceptOwnership(address newTarget) external {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;

import {ILSP20CallVerification} from "../../LSP20CallVerification/ILSP20CallVerification.sol";
import {ILSP20CallVerifier} from "../../LSP20CallVerification/ILSP20CallVerifier.sol";
import {ILSP14Ownable2Step} from "../../LSP14Ownable2Step/ILSP14Ownable2Step.sol";

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;

import {ILSP20CallVerification} from "../../LSP20CallVerification/ILSP20CallVerification.sol";
import {ILSP20CallVerifier} from "../../LSP20CallVerification/ILSP20CallVerifier.sol";
import {ILSP14Ownable2Step} from "../../LSP14Ownable2Step/ILSP14Ownable2Step.sol";

/**
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@
"test:reentrancyinit": "hardhat test --no-compile tests/Reentrancy/ReentrancyInit.test.ts",
"test:foundry": "forge test --no-match-test Skip -vvv --gas-report > gasreport.ansi",
"clean": "hardhat clean && rm -rf module common",
"build": "hardhat dodoc && prettier -w ./docs",
"build": "hardhat dodoc && ts-node scripts/interfaceIds.ts && prettier -w ./docs ",
"build:js": "vite build && dts-bundle-generator --config dtsconfig.json",
"package": "hardhat prepare-package",
"release": "run-s clean build package && standard-version",
"release": "run-s clean build package && standard-`version",
"remixd": "remixd -s . --remix-ide",
"linter": "solhint 'contracts/**/*.sol'",
"format": "prettier --write .",
Expand Down
1 change: 0 additions & 1 deletion scripts/ci/docs-generate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import fs from 'fs';
import path from 'path';
import { task } from 'hardhat/config';
import { HardhatPluginError } from 'hardhat/plugins';
import { TASK_COMPILE } from 'hardhat/builtin-tasks/task-names';
import { ethers } from 'ethers';
import pluralize from 'pluralize';
Expand Down
92 changes: 92 additions & 0 deletions scripts/interfaceIds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import fs from 'fs';
import { Align, getMarkdownTable, Row } from 'markdown-table-ts';
import hre from 'hardhat';

import { INTERFACE_IDS } from '../constants';

const ercInterfaceDescriptions = {
ERC165: 'Standard Interface Detection.',
ERC1271: 'Standard Signature Validation Method for Contracts.',
ERC725X: 'General executor.',
ERC725Y: 'General Data key-value store.',
};

const excludedInterfaces = ['ERC20', 'ERC223', 'ERC721', 'ERC721Metadata', 'ERC777', 'ERC1155'];

async function main() {
const interfaces = Object.entries(INTERFACE_IDS);

const table: Row[] = [];

// exclude ERC token interfaces
const filteredInterfaces = interfaces.filter(
([contract]) => !excludedInterfaces.includes(contract),
);

for (const [contract, interfaceId] of filteredInterfaces) {
let description = '';

if (contract.startsWith('ERC')) {
description = ercInterfaceDescriptions[contract];
} else {
const lspInterface = `I${contract}`;

// adjust the source path for LSP20 and LSP17 contracts
const folders = {
LSP20CallVerifier: 'LSP20CallVerification',
LSP17Extendable: 'LSP17ContractExtension',
LSP17Extension: 'LSP17ContractExtension',
};

let folder;

if (contract === 'LSP20CallVerifier' || contract.startsWith('LSP17')) {
folder = folders[contract];
} else {
folder = contract;
}

const source = `contracts/${folder}/${lspInterface}.sol:${lspInterface}`;
const build = await hre.artifacts.getBuildInfo(source);

const [path, name] = source.split(':');

let devdoc = build?.output?.contracts?.[path]?.[lspInterface]['devdoc'];

if (!devdoc) {
// search in the first implementation contract
const source = `contracts/${folder}/${contract}.sol:${contract}`;
const build = await hre.artifacts.getBuildInfo(source);

const [path, name] = source.split(':');

const contractDevDoc = build?.output?.contracts?.[path]?.[contract]['devdoc'];

if (contractDevDoc == undefined) {
throw new Error(`No devdoc for ${contract}`);
}

if (contractDevDoc.hasOwnProperty('title')) {
description = contractDevDoc.title;
}
} else {
if (devdoc.hasOwnProperty('title')) {
description = devdoc.title;
}
}
}

table.push([`**${contract}**`, `\`${interfaceId}\``, description]);
}

const result = getMarkdownTable({
table: {
head: ['Contract', 'Interface ID', 'Description'],
body: table,
},
alignment: [Align.Left, Align.Center, Align.Left],
});

fs.writeFileSync('docs/_interface_ids_table.mdx', result);
}
main();
26 changes: 12 additions & 14 deletions tests/LSP20CallVerification/LSP20CallVerification.behaviour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import {
FirstCallReturnInvalidMagicValue,
FirstCallReturnInvalidMagicValue__factory,
LSP0ERC725Account,
ILSP20CallVerification,
ILSP20CallVerification__factory,
ILSP20CallVerifier,
ILSP20CallVerifier__factory,
} from '../../types';

// constants
Expand Down Expand Up @@ -377,7 +377,7 @@ export const shouldBehaveLikeLSP20 = (buildContext: () => Promise<LSP20TestConte
let newUniversalProfile: UniversalProfile;

before(async () => {
firstCallReturnMagicValueContract = await smock.fake(ILSP20CallVerification__factory.abi);
firstCallReturnMagicValueContract = await smock.fake(ILSP20CallVerifier__factory.abi);
firstCallReturnMagicValueContract.lsp20VerifyCall.returns(
LSP20_MAGIC_VALUES.VERIFY_CALL.NO_POST_VERIFICATION,
);
Expand Down Expand Up @@ -405,7 +405,7 @@ export const shouldBehaveLikeLSP20 = (buildContext: () => Promise<LSP20TestConte
let newUniversalProfile: UniversalProfile;

before(async () => {
firstCallReturnMagicValueContract = await smock.fake(ILSP20CallVerification__factory.abi);
firstCallReturnMagicValueContract = await smock.fake(ILSP20CallVerifier__factory.abi);
firstCallReturnMagicValueContract.lsp20VerifyCall.returns(
LSP20_MAGIC_VALUES.VERIFY_CALL.NO_POST_VERIFICATION +
'0'.repeat(56) +
Expand Down Expand Up @@ -434,11 +434,11 @@ export const shouldBehaveLikeLSP20 = (buildContext: () => Promise<LSP20TestConte
});

describe('that implements verifyCall and verifyCallResult and both return magic value', () => {
let bothCallReturnMagicValueContract: FakeContract<ILSP20CallVerification>;
let bothCallReturnMagicValueContract: FakeContract<ILSP20CallVerifier>;
let newUniversalProfile: UniversalProfile;

before(async () => {
bothCallReturnMagicValueContract = await smock.fake(ILSP20CallVerification__factory.abi);
bothCallReturnMagicValueContract = await smock.fake(ILSP20CallVerifier__factory.abi);
bothCallReturnMagicValueContract.lsp20VerifyCall.returns(
LSP20_MAGIC_VALUES.VERIFY_CALL.WITH_POST_VERIFICATION,
);
Expand All @@ -465,11 +465,11 @@ export const shouldBehaveLikeLSP20 = (buildContext: () => Promise<LSP20TestConte
});

describe('that implements verifyCall and verifyCallResult and both return magic value plus additional data', () => {
let bothCallReturnMagicValueContract: FakeContract<ILSP20CallVerification>;
let bothCallReturnMagicValueContract: FakeContract<ILSP20CallVerifier>;
let newUniversalProfile: UniversalProfile;

before(async () => {
bothCallReturnMagicValueContract = await smock.fake(ILSP20CallVerification__factory.abi);
bothCallReturnMagicValueContract = await smock.fake(ILSP20CallVerifier__factory.abi);
bothCallReturnMagicValueContract.lsp20VerifyCall.returns(
LSP20_MAGIC_VALUES.VERIFY_CALL.WITH_POST_VERIFICATION +
'0'.repeat(56) +
Expand Down Expand Up @@ -504,11 +504,11 @@ export const shouldBehaveLikeLSP20 = (buildContext: () => Promise<LSP20TestConte
});

describe('that implements verifyCallResult but return invalid magicValue', () => {
let secondCallReturnFailureContract: FakeContract<ILSP20CallVerification>;
let secondCallReturnFailureContract: FakeContract<ILSP20CallVerifier>;
let newUniversalProfile: UniversalProfile;

before(async () => {
secondCallReturnFailureContract = await smock.fake(ILSP20CallVerification__factory.abi);
secondCallReturnFailureContract = await smock.fake(ILSP20CallVerifier__factory.abi);
secondCallReturnFailureContract.lsp20VerifyCall.returns(
LSP20_MAGIC_VALUES.VERIFY_CALL.WITH_POST_VERIFICATION,
);
Expand All @@ -530,13 +530,11 @@ export const shouldBehaveLikeLSP20 = (buildContext: () => Promise<LSP20TestConte
});

describe('that implements verifyCallResult but return an expanded magic value', () => {
let secondCallReturnExpandedValueContract: FakeContract<ILSP20CallVerification>;
let secondCallReturnExpandedValueContract: FakeContract<ILSP20CallVerifier>;
let newUniversalProfile: UniversalProfile;

before(async () => {
secondCallReturnExpandedValueContract = await smock.fake(
ILSP20CallVerification__factory.abi,
);
secondCallReturnExpandedValueContract = await smock.fake(ILSP20CallVerifier__factory.abi);
secondCallReturnExpandedValueContract.lsp20VerifyCall.returns(
LSP20_MAGIC_VALUES.VERIFY_CALL.WITH_POST_VERIFICATION,
);
Expand Down