Skip to content

[Add Test & Refactor] Std Functions #36

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 9 commits into from
May 1, 2024
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
4 changes: 4 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 @@ -52,6 +52,10 @@
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Setup Git user
run: |
git config --global user.email "github-actions@example.com"
git config --global user.name "GitHub Actions"
- name: Run forge install
run: |
mkdir /tmp/install-with-template-test
Expand Down
40 changes: 28 additions & 12 deletions devkit/MCTest.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Proxy as OZProxy} from "@oz.ucs/proxy/Proxy.sol";

import {System} from "devkit/system/System.sol";
import {DecodeErrorString} from "devkit/system/message/DecodeErrorString.sol";
import {Receive} from "mc-std/functions/Receive.sol";
import {Formatter} from "devkit/types/Formatter.sol";
import {ProxyUtils} from "@ucs.mc/proxy/ProxyUtils.sol";
import {Dummy} from "test/utils/Dummy.sol";

// 💬 ABOUT
// Meta Contract's default Test based on Forge Std Test
Expand All @@ -20,24 +24,36 @@ abstract contract MCTest is MCTestBase {
}

// 🌟 MC State Fuzzing Test
abstract contract MCStateFuzzingTest is MCTestBase { // solhint-disable-line payable-fallback
abstract contract MCStateFuzzingTest is MCTestBase, OZProxy { // solhint-disable-line payable-fallback
struct Function {
bytes4 selector;
address implementation;
}

mapping(bytes4 selector => address) implementations;
address target = address(this);
Function[] internal functions;
address dictionary;

constructor() {
System.Config().load();
implementations[bytes4(0)] = address(new Receive());
}

fallback(bytes calldata) external payable returns (bytes memory){
address opAddress = implementations[msg.sig];
require(opAddress != address(0), "Called implementation is not registered.");
(bool success, bytes memory data) = opAddress.delegatecall(msg.data);
if (success) {
return data;
} else {
// vm.expectRevert needs this.
revert(DecodeErrorString.decodeRevertReasonAndPanicCode(data));
}
function _use(bytes4 selector_, address impl_) internal {
functions.push(Function(selector_, impl_));
implementations[selector_] = impl_;
}

function _setDictionary(address dictionary_) internal {
dictionary = dictionary_;
vm.store(address(this), ProxyUtils.DICTIONARY_SLOT, Formatter.toBytes32(dictionary_));
}

function _implementation() internal view override returns (address) {
return implementations[msg.sig];
}

}

// 🌟 MC TEST for DevKit
Expand Down
26 changes: 13 additions & 13 deletions devkit/registry/StdFunctions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {Logger} from "devkit/system/Logger.sol";
import {Function} from "devkit/core/Function.sol";
// MC Std
import {Clone} from "mc-std/functions/Clone.sol";
import {GetDeps} from "mc-std/functions/GetDeps.sol";
import {GetFunctions} from "mc-std/functions/GetFunctions.sol";
import {FeatureToggle} from "mc-std/functions/protected/FeatureToggle.sol";
import {InitSetAdmin} from "mc-std/functions/protected/InitSetAdmin.sol";
import {UpgradeDictionary} from "mc-std/functions/protected/UpgradeDictionary.sol";
Expand All @@ -28,7 +28,7 @@ import {StdFacade} from "mc-std/interfaces/StdFacade.sol";
//////////////////////////////////////////////////////
struct StdFunctions {
Function initSetAdmin;
Function getDeps;
Function getFunctions;
Function clone;
TypeStatus status;
}
Expand Down Expand Up @@ -57,7 +57,7 @@ library StdFunctionsLib {
uint pid = std.startProcess("fetch");
std.startBuilding();
std .fetch_InitSetAdmin()
.fetch_GetDeps()
.fetch_GetFunctions()
.fetch_Clone();
std.finishBuilding();
return std.finishProcess(pid);
Expand All @@ -72,11 +72,11 @@ library StdFunctionsLib {
return std.finishProcess(pid);
}

function fetch_GetDeps(StdFunctions storage std) internal returns(StdFunctions storage) {
uint pid = std.startProcess("fetch_GetDeps");
std.getDeps .fetch("GetDeps")
.assignSelector(GetDeps.getDeps.selector);
Logger.logDebug(std.getDeps.toString());
function fetch_GetFunctions(StdFunctions storage std) internal returns(StdFunctions storage) {
uint pid = std.startProcess("fetch_GetFunctions");
std.getFunctions .fetch("GetFunctions")
.assignSelector(GetFunctions.getFunctions.selector);
Logger.logDebug(std.getFunctions.toString());
return std.finishProcess(pid);
}

Expand All @@ -97,7 +97,7 @@ library StdFunctionsLib {
uint pid = std.startProcess("deployIfNotExists");
std.startBuilding();
std .deployIfNotExists_InitSetAdmin()
.deployIfNotExists_GetDeps()
.deployIfNotExists_GetFunctions()
.deployIfNotExists_Clone();
std.finishBuilding();
return std.finishProcess(pid);
Expand All @@ -111,10 +111,10 @@ library StdFunctionsLib {
return std.finishProcess(pid);
}

function deployIfNotExists_GetDeps(StdFunctions storage std) internal returns(StdFunctions storage) {
uint pid = std.startProcess("deployIfNotExists_GetDeps");
if (std.getDeps.hasNotContract()) {
std.getDeps.assignImplementation(address(new GetDeps()));
function deployIfNotExists_GetFunctions(StdFunctions storage std) internal returns(StdFunctions storage) {
uint pid = std.startProcess("deployIfNotExists_GetFunctions");
if (std.getFunctions.hasNotContract()) {
std.getFunctions.assignImplementation(address(new GetFunctions()));
}
return std.finishProcess(pid);
}
Expand Down
4 changes: 2 additions & 2 deletions devkit/registry/StdRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {Bundle} from "devkit/core/Bundle.sol";
import {StdFunctions} from "devkit/registry/StdFunctions.sol";
// MC Std
import {Clone} from "mc-std/functions/Clone.sol";
import {GetDeps} from "mc-std/functions/GetDeps.sol";
import {GetFunctions} from "mc-std/functions/GetFunctions.sol";
import {FeatureToggle} from "mc-std/functions/protected/FeatureToggle.sol";
import {InitSetAdmin} from "mc-std/functions/protected/InitSetAdmin.sol";
import {UpgradeDictionary} from "mc-std/functions/protected/UpgradeDictionary.sol";
Expand Down Expand Up @@ -60,7 +60,7 @@ library StdRegistryLib {
uint pid = registry.startProcess("configureStdBundle_All");
registry.all.assignName("ALL_STD_FUNCTIONS")
.pushFunction(registry.functions.initSetAdmin)
.pushFunction(registry.functions.getDeps)
.pushFunction(registry.functions.getFunctions)
.pushFunction(registry.functions.clone)
.assignFacade(address(new StdFacade()));
return registry.finishProcess(pid);
Expand Down
2 changes: 1 addition & 1 deletion devkit/system/Validator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ library Validator {
function ValidateBuilder(StdFunctions storage std) internal view returns(bool) {
return (
Validator.ValidateBuilder(std.initSetAdmin) &&
Validator.ValidateBuilder(std.getDeps) &&
Validator.ValidateBuilder(std.getFunctions) &&
Validator.ValidateBuilder(std.clone)
);
}
Expand Down
4 changes: 4 additions & 0 deletions devkit/types/Formatter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ library Formatter {
return vm.toString(addr);
}

function toBytes32(address addr) internal pure returns(bytes32) {
return bytes32(uint256(uint160(addr)));
}

function toString(bytes4 selector) internal pure returns (string memory) {
return vm.toString(selector).substring(10);
}
Expand Down
5 changes: 5 additions & 0 deletions devkit/utils/ForgeHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {stdToml} from "forge-std/StdToml.sol";
// MC Devkit
import {Logger} from "devkit/system/Logger.sol";
import {Parser} from "devkit/types/Parser.sol";
import {ProxyUtils} from "@ucs.mc/proxy/ProxyUtils.sol";

// Constants
/// @dev address(uint160(uint256(keccak256("hevm cheat code"))));
Expand Down Expand Up @@ -48,6 +49,10 @@ library ForgeHelper {
return address(uint160(uint256(vm.load(target, slot))));
}

function getDictionaryAddress(address proxy) internal view returns(address) {
return loadAddress(proxy, ProxyUtils.DICTIONARY_SLOT);
}

function assumeAddressIsNotReserved(address addr) internal pure {
vm.assume(
addr != address(1) &&
Expand Down
2 changes: 1 addition & 1 deletion lib/ucs-contracts
17 changes: 7 additions & 10 deletions src/std/functions/Clone.sol
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import {Proxy} from "@ucs.mc/proxy/Proxy.sol";
import {ProxyCreator} from "./internal/ProxyCreator.sol";
import {ProxyUtils} from "@ucs.mc/proxy/ProxyUtils.sol";

/**
< MC Standard Function >
@title Clone
@custom:version 0.1.0
@custom:schema v0.1.0
/** < MC Standard Function >
* @title Clone
* @custom:version v0.1.0
* @custom:schema none
*/
contract Clone {
/// DO NOT USE STORAGE DIRECTLY !!!
event ProxyCloned(address proxy);

function clone(bytes calldata initData) external returns (address proxy) {
proxy = address(new Proxy(ProxyUtils.getDictionary(), initData));
emit ProxyCloned(proxy);
function clone(bytes calldata initData) external returns(address proxy) {
proxy = ProxyCreator.create(ProxyUtils.getDictionary(), initData);
}

}
17 changes: 7 additions & 10 deletions src/std/functions/Create.sol
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import {Proxy} from "@ucs.mc/proxy/Proxy.sol";
import {ProxyCreator} from "./internal/ProxyCreator.sol";

/**
< MC Standard Function >
@title Create
@custom:version 0.1.0
@custom:schema v0.1.0
/** < MC Standard Function >
* @title Create
* @custom:version v0.1.0
* @custom:schema none
*/
contract Create {
/// DO NOT USE STORAGE DIRECTLY !!!
event ProxyCreated(address dictionary, address proxy);

function create(address dictionary, bytes calldata initData) external returns (address proxy) {
proxy = address(new Proxy(dictionary, initData));
emit ProxyCreated(dictionary, proxy);
function create(address dictionary, bytes calldata initData) external returns(address proxy) {
proxy = ProxyCreator.create(dictionary, initData);
}

}
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import {Dep} from "../storage/Schema.sol";

import {ProxyUtils} from "@ucs.mc/proxy/ProxyUtils.sol";
import {IDictionary} from "@ucs.mc/dictionary/IDictionary.sol";

/**
< MC Standard Function >
@title GetDeps
@custom:version 0.1.0
@custom:schema v0.1.0
/** < MC Standard Function >
* @title GetFunctions
* @custom:version v0.1.0
* @custom:schema none
*/
contract GetDeps {
contract GetFunctions {
/// DO NOT USE STORAGE DIRECTLY !!!
struct Function {
bytes4 selector;
address implementation;
}

function getDeps() external view returns(Dep[] memory) {
function getFunctions() external view returns(Function[] memory) {
IDictionary dictionary = IDictionary(ProxyUtils.getDictionary());
bytes4[] memory selectors = dictionary.supportsInterfaces();
Dep[] memory deps = new Dep[](selectors.length);
Function[] memory deps = new Function[](selectors.length);
for (uint i; i < selectors.length; ++i) {
deps[i].selector = selectors[i];
deps[i].implementation = dictionary.getImplementation(selectors[i]);
Expand Down
11 changes: 5 additions & 6 deletions src/std/functions/Receive.sol
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

/**
< MC Standard Function >
@title Receive
@custom:version 0.1.0
@custom:schema v0.1.0
/** < MC Standard Function >
* @title Receive
* @custom:version v0.1.0
* @custom:schema none
*/
contract Receive {
/// DO NOT USE STORAGE DIRECTLY !!!
event Received(address from, uint256 amount);

event Received(address from, uint256 amount);
receive() external payable {
emit Received(msg.sender, msg.value);
}
Expand Down
22 changes: 0 additions & 22 deletions src/std/functions/internal/Clone.sol

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ pragma solidity ^0.8.22;

import {Proxy} from "@ucs.mc/proxy/Proxy.sol";

/**
< MC Standard Function >
@title Create
@custom:version 0.1.0
@custom:schema v0.1.0
/** < MC Standard Helper Library >
* @title Proxy Creator
* @custom:version v0.1.0
* @custom:schema none
*/
library Create {
/// DO NOT USE STORAGE DIRECTLY !!!
library ProxyCreator {
event ProxyCreated(address dictionary, address proxy);

function _create(address dictionary, bytes calldata initData) internal returns (address proxy) {
function create(address dictionary, bytes calldata initData) internal returns(address proxy) {
proxy = address(new Proxy(dictionary, initData));
emit ProxyCreated(dictionary, proxy);
}

}
4 changes: 2 additions & 2 deletions src/std/interfaces/IStd.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
pragma solidity ^0.8.24;

import {IProxy} from "@ucs.mc/proxy/IProxy.sol";
import {Dep} from "../storage/Schema.sol";
import {GetFunctions} from "mc-std/functions/GetFunctions.sol";

interface IStd is IProxy {
function clone(bytes calldata initData) external returns (address proxy);
function getDeps() external view returns(Dep[] memory);
function getFunctions() external view returns(GetFunctions.Function[] memory);
function featureToggle(bytes4 selector) external;
function initSetAdmin(address admin) external;
function upgradeDictionary(address newDictionary) external;
Expand Down
4 changes: 2 additions & 2 deletions src/std/interfaces/StdFacade.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
pragma solidity ^0.8.24;

import {IStd} from "./IStd.sol";
import {Dep} from "../storage/Schema.sol";
import {GetFunctions} from "mc-std/functions/GetFunctions.sol";

contract StdFacade is IStd {
function clone(bytes calldata initData) external returns (address proxy) {}
function getDeps() external view returns(Dep[] memory) {}
function getFunctions() external view returns(GetFunctions.Function[] memory) {}
function featureToggle(bytes4 selector) external {}
function initSetAdmin(address admin) external {}
function upgradeDictionary(address newDictionary) external {}
Expand Down
Loading
Loading