Skip to content

Improve Type Safety & DevKit Testing #35

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

Merged
merged 111 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
8c413c8
CI: Add install with template
kaihiroi Apr 7, 2024
b4b7815
Update deploy script
kaihiroi Apr 7, 2024
68eb759
Update MCSetupTest
kaihiroi Apr 7, 2024
24f38ef
Add toBytes to StringUtils
kaihiroi Apr 7, 2024
0c55034
Add message method to ERR lib
kaihiroi Apr 7, 2024
71db9d5
Fix Function to use memory params
kaihiroi Apr 7, 2024
7285289
Add DummyFunction contract for test
kaihiroi Apr 7, 2024
c3cd35c
Add {use} tests to MCBundleTest
kaihiroi Apr 7, 2024
f6fe6a9
Update {use} MCBundleTest
kaihiroi Apr 7, 2024
a2e9d34
Add useFacade tests
kaihiroi Apr 7, 2024
0abf14b
Update useFacade()
kaihiroi Apr 7, 2024
7941383
Chore update var name bundle & function
kaihiroi Apr 7, 2024
9a63891
Rename ucs to core
kaihiroi Apr 7, 2024
d4b97df
Update Function: externalize debug methods
kaihiroi Apr 7, 2024
8b9e6dd
Update Function: externalize Libs, FunctionLib, Check, LogLib
kaihiroi Apr 8, 2024
ae27e5b
update file location: method files
kaihiroi Apr 8, 2024
c85e313
fix typo
kaihiroi Apr 8, 2024
eb0d14a
Move core/Function
kaihiroi Apr 8, 2024
e2af6ce
Move core/functions
kaihiroi Apr 8, 2024
e8665b3
Adjust Path
kaihiroi Apr 8, 2024
74492e7
Remove function's methods from bundle registry
kaihiroi Apr 8, 2024
133ea6b
Adjust name change
kaihiroi Apr 8, 2024
3179c7c
Move dictionary to core/
kaihiroi Apr 8, 2024
bbc120e
Move proxy to core/
kaihiroi Apr 8, 2024
5ce0c76
Separate process method from StdFunctionsLib
kaihiroi Apr 8, 2024
76ec827
chore update std functions
kaihiroi Apr 8, 2024
5ea4680
Separate ProxyRegistryLib file
kaihiroi Apr 8, 2024
90450a2
Separate process methods from ProxyRegistryLib
kaihiroi Apr 8, 2024
3518f19
Separate BundleLib from Bundle file
kaihiroi Apr 8, 2024
69e41b6
Separate process methods from BundleLib
kaihiroi Apr 8, 2024
b88261d
Separate DictionaryRegistryLib from DictionaryRegistry file
kaihiroi Apr 8, 2024
4bd35c8
Separate process methods from DictionaryRegistryLib
kaihiroi Apr 8, 2024
2d87147
Separate BundleRegistryLib from BundleRegistry file
kaihiroi Apr 8, 2024
b2576fd
Separate process methods from BundleRegistryLib
kaihiroi Apr 8, 2024
661a143
Separate process methods from ProxyLib
kaihiroi Apr 8, 2024
03220c9
Separate DictionaryLib file
kaihiroi Apr 8, 2024
86e990f
Separate process methods from DictionaryLib
kaihiroi Apr 8, 2024
59fa6b3
Separate FunctionRegistryLib
kaihiroi Apr 8, 2024
df4c91d
chore update cores
kaihiroi Apr 8, 2024
c2ea4ff
Externalize Parser & Dumper
kaihiroi Apr 8, 2024
dd71a43
Rename Parser & Dumper
kaihiroi Apr 8, 2024
a7b3860
Externalize Inspector
kaihiroi Apr 9, 2024
8248d95
chore update pretty
kaihiroi Apr 9, 2024
7a741c1
Separate MockRegistry from Proxy, Dictionary registry
kaihiroi Apr 9, 2024
b30eac6
Externalize naming from MockRegistry
kaihiroi Apr 9, 2024
f2d2cb5
Externalize MappingAnalyzer (formerly Naming)
kaihiroi Apr 9, 2024
a66dd10
Create Require
kaihiroi Apr 9, 2024
27b75e6
Update BundleLib
kaihiroi Apr 9, 2024
6b61368
Rename Check & Require to Valid
kaihiroi Apr 9, 2024
ca123b3
Update chore bundle file
kaihiroi Apr 9, 2024
37780f9
Merge FunctionLib
kaihiroi Apr 9, 2024
8a2c0f4
Update FunctionLib to improve type safety
kaihiroi Apr 9, 2024
354757a
Update ProxyLib
kaihiroi Apr 9, 2024
b490cbb
Update DictionaryLib
kaihiroi Apr 9, 2024
ee678d7
Update BundleRegistry Lib
kaihiroi Apr 9, 2024
4e6e526
Separate valid and Require
kaihiroi Apr 9, 2024
99a5714
Update Require
kaihiroi Apr 10, 2024
2a7ef87
Arrange directory structure
kaihiroi Apr 10, 2024
e167d91
Remove unused files
kaihiroi Apr 10, 2024
71b93d8
chore update
kaihiroi Apr 10, 2024
15105c9
Update BundleRegistry
kaihiroi Apr 10, 2024
15de0a4
Externalize Current
kaihiroi Apr 10, 2024
f204848
Update FunctionRegistry to use Current
kaihiroi Apr 10, 2024
986c4a7
Update DictionaryRegistry to use Current
kaihiroi Apr 10, 2024
86d0db9
Update Proxy Registry
kaihiroi Apr 10, 2024
c955d51
Add deploy() to proxy registry
kaihiroi Apr 10, 2024
3d5a6b1
Add deploy() to DictionaryRegistry
kaihiroi Apr 10, 2024
dbf2ecf
chore update
kaihiroi Apr 10, 2024
c2d4c9a
Update StdFunctions
kaihiroi Apr 10, 2024
8991616
Update StdRegistry: merge stdBundle
kaihiroi Apr 10, 2024
1b2a48b
Improve TypeGuard for StdFunction
kaihiroi Apr 10, 2024
ee61119
Improve Dictionary type safety
kaihiroi Apr 10, 2024
ae3bf35
Improve DictionaryRegistry type safety
kaihiroi Apr 10, 2024
9bd9284
Update ProxyRegistry type safety
kaihiroi Apr 10, 2024
8608dc2
Update registry to use type check
kaihiroi Apr 11, 2024
19a54ab
Move & Rename mocks
kaihiroi Apr 11, 2024
248391c
Update ProxyRegistry & DictionaryRegistry
kaihiroi Apr 11, 2024
c1c8394
chore update proxy & registry
kaihiroi Apr 11, 2024
dedea04
Remove MockRegistry
kaihiroi Apr 11, 2024
b7d75fc
Update create mock proxy&dictionary
kaihiroi Apr 11, 2024
0d12bd6
Update createMock methods
kaihiroi Apr 11, 2024
fd44c43
Update FunctionRegistry to use register()
kaihiroi Apr 11, 2024
b3e27ac
Update BundleRegistry to improve type safety
kaihiroi Apr 11, 2024
3863b0f
chore update
kaihiroi Apr 11, 2024
f661cdd
Update directory structure
kaihiroi Apr 11, 2024
a5d529b
Move Current to registry/
kaihiroi Apr 11, 2024
179dce7
Restructure
kaihiroi Apr 11, 2024
c190c76
Improve validation & debugger
kaihiroi Apr 11, 2024
b59d111
Use Validate methods instead of validate()
kaihiroi Apr 12, 2024
f82357d
update validate method
kaihiroi Apr 12, 2024
bba7191
Improve Validation
kaihiroi Apr 12, 2024
a8c0a30
Remove ValidationHandler file
kaihiroi Apr 12, 2024
43b11d3
Create Type Converter
kaihiroi Apr 12, 2024
0b47b01
Move primitive method to converter and inspector
kaihiroi Apr 12, 2024
ad67480
Rename MappingAnalizer to mapping/NameGenerator
kaihiroi Apr 12, 2024
13c6cc3
chore
kaihiroi Apr 12, 2024
2769756
Move debug files
kaihiroi Apr 12, 2024
19989b4
Remove throwError
kaihiroi Apr 12, 2024
1625bac
update & rename debugger
kaihiroi Apr 12, 2024
b64a7f2
add config option "RECORD_EXECUTION_PROCESS"
kaihiroi Apr 12, 2024
460a71c
Update Debugger & Logger, Messages
kaihiroi Apr 14, 2024
b9a1875
Verifiable Check without Broadcast
kaihiroi Apr 14, 2024
ea348b3
Create devkit/system
kaihiroi Apr 14, 2024
5278076
update noBroadcast validation
kaihiroi Apr 15, 2024
6f02022
Merge config to system
kaihiroi Apr 15, 2024
fd03672
merge debugger into system
kaihiroi Apr 15, 2024
213ac08
Update ProcessLib
kaihiroi Apr 15, 2024
36e126e
rename parser to formatter
kaihiroi Apr 15, 2024
a18c757
Update Formatter
kaihiroi Apr 15, 2024
de4ac20
Remove oz lib
kaihiroi Apr 15, 2024
206e18e
Update UCS Contracts Lib
kaihiroi Apr 15, 2024
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
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Continuous Integration

Check warning on line 1 in .github/workflows/ci.yml

View workflow job for this annotation

GitHub Actions / review-workflow-changes

1:1 [document-start] missing document start "---"

on:

Check warning on line 3 in .github/workflows/ci.yml

View workflow job for this annotation

GitHub Actions / review-workflow-changes

3:1 [truthy] truthy value should be one of [false, true]
pull_request:
types:
- opened
Expand Down Expand Up @@ -42,6 +42,23 @@
run: |
forge test

install-with-template-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Run forge install
run: |
mkdir /tmp/install-with-template-test
cd /tmp/install-with-template-test
forge init mc-example-project -t metacontract/template
forge test

# slither:
# runs-on: ubuntu-latest
# steps:
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,3 @@
[submodule "lib/ucs-contracts"]
path = lib/ucs-contracts
url = https://github.com/ecdysisxyz/ucs-contracts
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
24 changes: 14 additions & 10 deletions devkit/MCDevKit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,29 @@
pragma solidity ^0.8.24;

// Registries
import {FunctionRegistry} from "devkit/ucs/functions/FunctionRegistry.sol";
import {DictionaryRegistry} from "devkit/ucs/dictionary/DictionaryRegistry.sol";
import {ProxyRegistry} from "devkit/ucs/proxy/ProxyRegistry.sol";
import {StdRegistry} from "devkit/registry/StdRegistry.sol";
import {FunctionRegistry} from "devkit/registry/FunctionRegistry.sol";
import {BundleRegistry} from "devkit/registry/BundleRegistry.sol";
import {DictionaryRegistry} from "devkit/registry/DictionaryRegistry.sol";
import {ProxyRegistry} from "devkit/registry/ProxyRegistry.sol";

// Global Methods
import {MCSetupLib} from "devkit/global/MCSetupLib.sol";
import {MCBundleLib} from "devkit/global/MCBundleLib.sol";
import {MCDeployLib} from "devkit/global/MCDeployLib.sol";
import {MCFinderLib} from "devkit/global/MCFinderLib.sol";
import {MCContextLib} from "devkit/global/MCContextLib.sol";
import {MCTestLib} from "devkit/global/MCTestLib.sol";
import {MCDebugLib} from "devkit/global/MCDebugLib.sol";
import {MCSetupLib} from "devkit/utils/global/MCSetupLib.sol";
import {MCBundleLib} from "devkit/utils/global/MCBundleLib.sol";
import {MCDeployLib} from "devkit/utils/global/MCDeployLib.sol";
import {MCFinderLib} from "devkit/utils/global/MCFinderLib.sol";
import {MCContextLib} from "devkit/utils/global/MCContextLib.sol";
import {MCTestLib} from "devkit/utils/global/MCTestLib.sol";
import {MCDebugLib} from "devkit/utils/global/MCDebugLib.sol";


/********************************
🌟 Meta Contract DevKit
*********************************/
struct MCDevKit {
StdRegistry std;
FunctionRegistry functions;
BundleRegistry bundle;
DictionaryRegistry dictionary;
ProxyRegistry proxy;
}
Expand Down
12 changes: 6 additions & 6 deletions devkit/MCScript.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Config} from "devkit/config/Config.sol";
import {System} from "devkit/system/System.sol";

// 💬 ABOUT
// Meta Contract's default Script based on Forge Std Script
Expand All @@ -12,16 +12,16 @@ import {MCScriptBase} from "./MCBase.sol";
// ⭐️ MC SCRIPT
abstract contract MCScript is MCScriptBase {
constructor() {
Config().load();
if (Config().DEBUG_MODE) mc.startDebug();
if (Config().SETUP_STD_FUNCS) mc.setupStdFunctions();
mc.loadConfig();
mc.startDebug();
if (System.Config().SETUP_STD_FUNCS) mc.setupStdFunctions();
}
}

// ⭐️ MC SCRIPT without Setup
abstract contract MCScriptWithoutSetup is MCScriptBase {
constructor() {
Config().load();
if (Config().DEBUG_MODE) mc.startDebug();
mc.loadConfig();
mc.startDebug();
}
}
12 changes: 6 additions & 6 deletions devkit/MCTest.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Config} from "devkit/config/Config.sol";
import {DecodeErrorString} from "./error/DecodeErrorString.sol";
import {System} from "devkit/system/System.sol";
import {DecodeErrorString} from "devkit/system/message/DecodeErrorString.sol";

// 💬 ABOUT
// Meta Contract's default Test based on Forge Std Test
Expand All @@ -13,9 +13,9 @@ import {MCTestBase} from "./MCBase.sol";
// ⭐️ MC TEST
abstract contract MCTest is MCTestBase {
constructor() {
Config().load();
if (Config().DEBUG_MODE) mc.startDebug();
if (Config().SETUP_STD_FUNCS) mc.setupStdFunctions();
System.Config().load();
if (System.Config().DEBUG_MODE) mc.startDebug();
if (System.Config().SETUP_STD_FUNCS) mc.setupStdFunctions();
}
}

Expand Down Expand Up @@ -47,7 +47,7 @@ abstract contract MCStateFuzzingTest is MCTestBase {
// 🌟 MC TEST for DevKit
abstract contract MCDevKitTest is MCTestBase {
constructor() {
Config().load();
System.Config().load();
mc.stopLog();
}
}
71 changes: 71 additions & 0 deletions devkit/core/Bundle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/**---------------------
Support Methods
-----------------------*/
import {ProcessLib} from "devkit/system/debug/Process.sol";
using ProcessLib for Bundle global;
import {Inspector} from "devkit/types/Inspector.sol";
using Inspector for Bundle global;
import {TypeGuard, TypeStatus} from "devkit/types/TypeGuard.sol";
using TypeGuard for Bundle global;
// Validation
import {Validate} from "devkit/system/validate/Validate.sol";

// Core Type
import {Function} from "devkit/core/Function.sol";


/**================
🗂️ Bundle
==================*/
using BundleLib for Bundle global;
struct Bundle {
string name;
Function[] functions;
address facade;
TypeStatus status;
}
library BundleLib {

/**--------------------
📛 Assign Name
----------------------*/
function assignName(Bundle storage bundle, string memory name) internal returns(Bundle storage) {
uint pid = bundle.startProcess("assignName");
Validate.MUST_BundleNotLocked(bundle);
Validate.MUST_NotEmptyName(name);
bundle.name = name;
return bundle.building().finishProcess(pid);
}

/**-------------------------
🧩 Push Function(s)
---------------------------*/
function pushFunction(Bundle storage bundle, Function storage func) internal returns(Bundle storage) {
uint pid = bundle.startProcess("pushFunction");
Validate.MUST_BundleNotLocked(bundle);
Validate.MUST_completed(func);
Validate.MUST_notHave(bundle, func);
bundle.functions.push(func);
return bundle.building().finishProcess(pid);
}
function pushFunctions(Bundle storage bundle, Function[] storage functions) internal returns(Bundle storage) {
uint pid = bundle.startProcess("pushFunctions");
for (uint i; i < functions.length; ++i) {
bundle.pushFunction(functions[i]);
}
return bundle.building().finishProcess(pid);
}

/**----------------------
🪟 Assign Facade
------------------------*/
function assignFacade(Bundle storage bundle, address facade) internal returns(Bundle storage) {
uint pid = bundle.startProcess("assignFacade");
Validate.MUST_AddressIsContract(facade);
bundle.facade = facade;
return bundle.building().finishProcess(pid);
}

}
154 changes: 154 additions & 0 deletions devkit/core/Dictionary.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/**---------------------
Support Methods
-----------------------*/
import {ProcessLib} from "devkit/system/debug/Process.sol";
using ProcessLib for Dictionary global;
import {Params} from "devkit/system/debug/Params.sol";
import {Inspector} from "devkit/types/Inspector.sol";
using Inspector for Dictionary global;
using Inspector for bytes4;
import {ForgeHelper} from "devkit/utils/ForgeHelper.sol";
// Validation
import {Validate} from "devkit/system/validate/Validate.sol";
import {TypeGuard, TypeStatus} from "devkit/types/TypeGuard.sol";
using TypeGuard for Dictionary global;

// Mock
import {DictionaryMock} from "devkit/mocks/DictionaryMock.sol";
// External Libs
import {IDictionary} from "@ucs.mc/dictionary/IDictionary.sol";
import {Dictionary as UCSDictionary} from "@ucs.mc/dictionary/Dictionary.sol";

// Core Types
import {Function} from "devkit/core/Function.sol";
import {Bundle} from "devkit/core/Bundle.sol";


/**====================
📚 Dictionary
======================*/
using DictionaryLib for Dictionary global;
struct Dictionary {
address addr;
DictionaryKind kind;
TypeStatus status;
}
library DictionaryLib {
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
🚀 Deploy Dictionary
🔂 Duplicate Dictionary
🧩 Set Function or Bundle
🪟 Upgrade Facade
🤖 Create Dictionary Mock
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/**-------------------------
🚀 Deploy Dictionary
---------------------------*/
function deploy(address owner) internal returns(Dictionary memory) {
uint pid = ProcessLib.startDictionaryLibProcess("deploy");
Validate.MUST_AddressIsNotZero(owner);
/// @dev Until Etherscan supports UCS, we are deploying contracts with additional features for Etherscan compatibility by default.
return Dictionary({
addr: address(new UCSDictionary(owner)),
kind: DictionaryKind.Verifiable,
status: TypeStatus.Building
}).finishProcess(pid);
}

/**----------------------------
🔂 Duplicate Dictionary
------------------------------*/
function duplicate(Dictionary memory toDictionary, Dictionary memory fromDictionary) internal returns(Dictionary memory) {
uint pid = ProcessLib.startDictionaryLibProcess("duplicate");
Validate.MUST_haveContract(toDictionary);
Validate.MUST_haveContract(fromDictionary);

address toAddr = toDictionary.addr;
address fromAddr = fromDictionary.addr;

bytes4[] memory _selectors = IDictionary(fromAddr).supportsInterfaces();
for (uint i; i < _selectors.length; ++i) {
bytes4 _selector = _selectors[i];
if (_selector.isEmpty()) continue;
toDictionary.set(_selector, IDictionary(fromAddr).getImplementation(_selector));
}

return toDictionary.finishProcess(pid);
}
function duplicate(Dictionary memory fromDictionary) internal returns(Dictionary memory) {
return duplicate(deploy(ForgeHelper.msgSender()), fromDictionary);
}

/**-----------------------------
🧩 Set Function or Bundle
-------------------------------*/
function set(Dictionary memory dictionary, bytes4 selector, address implementation) internal returns(Dictionary memory) {
uint pid = ProcessLib.startDictionaryLibProcess("set", Params.append(selector, implementation));
Validate.MUST_haveContract(dictionary);
Validate.MUST_Bytes4NotEmpty(selector);
Validate.MUST_AddressIsContract(implementation);
IDictionary(dictionary.addr).setImplementation({
functionSelector: selector,
implementation: implementation
});
return dictionary.finishProcess(pid);
}
function set(Dictionary memory dictionary, Function memory func) internal returns(Dictionary memory) {
uint pid = ProcessLib.startDictionaryLibProcess("set", Params.append(func.name));
return set(dictionary, func.selector, func.implementation).finishProcess(pid);
}
function set(Dictionary memory dictionary, Bundle storage bundle) internal returns(Dictionary memory) {
uint pid = ProcessLib.startDictionaryLibProcess("set", Params.append(bundle.name));

Function[] memory functions = bundle.functions;

for (uint i; i < functions.length; ++i) {
set(dictionary, functions[i]);
}

// TODO Generate Facade
// if (dictionary.isVerifiable()) {
// dictionary.upgradeFacade(bundle.facade);
// }

return dictionary.finishProcess(pid);
}

/**----------------------
🪟 Upgrade Facade
------------------------*/
function upgradeFacade(Dictionary memory dictionary, address newFacade) internal returns(Dictionary memory) {
uint pid = ProcessLib.startDictionaryLibProcess("upgradeFacade");
Validate.MUST_AddressIsContract(newFacade);
Validate.MUST_Verifiable(dictionary);
IDictionary(dictionary.addr).upgradeFacade(newFacade);
return dictionary.finishProcess(pid);
}

/**------------------------------
🤖 Create Dictionary Mock
--------------------------------*/
function createMock(address owner, Function[] memory functions) internal returns(Dictionary memory) {
uint pid = ProcessLib.startDictionaryLibProcess("createMock");
return Dictionary({
addr: address(new DictionaryMock(owner, functions)),
kind: DictionaryKind.Mock,
status: TypeStatus.Building
}).finishProcess(pid);
}

}


/**--------------------
Dictionary Kind
----------------------*/
enum DictionaryKind {
undefined,
Verifiable,
Mock
}
using Inspector for DictionaryKind global;
Loading
Loading