From 9971873fc0c71fd9208e9bb6af499478c810ead2 Mon Sep 17 00:00:00 2001 From: Timidan Date: Tue, 8 Nov 2022 13:52:12 +0100 Subject: [PATCH 1/4] fix overlaps --- contracts/Vault/VaultDiamond.sol | 66 +++++--------- contracts/Vault/facets/DiamondCutFacet.sol | 8 +- contracts/Vault/facets/ModuleManagerFacet.sol | 17 ++++ contracts/Vault/facets/OwnershipFacet.sol | 11 +++ contracts/Vault/libraries/LibArrayHelpers.sol | 2 +- .../Vault/libraries/LibStorageBinder.sol | 20 ++--- .../VaultFactory/VaultFactoryDiamond.sol | 24 +----- .../facets/ModuleupgraderFacet.sol | 24 ++++++ .../VaultFactory/facets/VaultSpawnerFacet.sol | 85 ++++--------------- .../VaultFactory/libraries/LibAppStorage.sol | 48 ----------- contracts/interfaces/IVaultDiamond.sol | 2 +- lib/solmate.git | 2 +- 12 files changed, 105 insertions(+), 204 deletions(-) create mode 100644 contracts/Vault/facets/ModuleManagerFacet.sol create mode 100644 contracts/Vault/facets/OwnershipFacet.sol create mode 100644 contracts/VaultFactory/facets/ModuleupgraderFacet.sol delete mode 100644 contracts/VaultFactory/libraries/LibAppStorage.sol diff --git a/contracts/Vault/VaultDiamond.sol b/contracts/Vault/VaultDiamond.sol index 6d2d4c7..e7f3970 100644 --- a/contracts/Vault/VaultDiamond.sol +++ b/contracts/Vault/VaultDiamond.sol @@ -1,12 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.4; -/******************************************************************************\ -* Author: Nick Mudge (https://twitter.com/mudgen) -* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 -* -* Implementation of a diamond. -/******************************************************************************/ +/** + * Implementation of a diamond. + * /***************************************************************************** + */ import {LibDiamond} from "./libraries/LibDiamond.sol"; import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; @@ -20,42 +18,26 @@ import {LibStorageBinder} from "./libraries/LibStorageBinder.sol"; import "../interfaces/IVaultDiamond.sol"; contract VaultDiamond { - bool _init; - - constructor() payable { - address _contractOwner = tx.origin; - LibDiamond.setVaultOwner(_contractOwner); - } - - function init(address _diamondCutFacet, address _backup) public { - VaultData storage vaultData = LibStorageBinder - ._bindAndReturnVaultStorage(); - assert(!_init); - assert( - msg.sender == LibDiamond.vaultOwner() || - tx.origin == LibDiamond.vaultOwner() - ); - // Add the diamondCut external function from the diamondCutFacet - IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1); - bytes4[] memory functionSelectors = new bytes4[](2); - functionSelectors[0] = IDiamondCut.diamondCut.selector; - functionSelectors[1] = IVaultDiamond.tempOwner.selector; - cut[0] = IDiamondCut.FacetCut({ - facetAddress: _diamondCutFacet, - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: functionSelectors - }); - - LibDiamond.diamondCut(cut, address(0), ""); - vaultData.backupAddress = _backup; - _init = true; + address public vaultFactoryDiamond; + + constructor(IDiamondCut.FacetCut[] memory _selectorModule,IDiamondCut.FacetCut[] memory _tokenModule, address _vaultOwner) payable { + LibDiamond.diamondCut(_selectorModule, address(0), ""); + LibDiamond.diamondCut(_tokenModule, address(0), ""); + //set module installation record to true + FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + fsData.activeModule["Selector"]=true; + fsData.activeModule["Token"]=true; + fsData.activeModules.push("Selector"); + fsData.activeModules.push("Token"); + LibDiamond.setVaultOwner(_vaultOwner); + vaultFactoryDiamond=msg.sender; } - + // Find facet for function that is called and execute the // function if a facet is found and return any value. + fallback() external payable { - FacetAndSelectorData storage fsData = LibStorageBinder - ._bindAndReturnFacetStorage(); + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); // get facet from function selector address facet = fsData.selectorToFacetAndPosition[msg.sig].facetAddress; @@ -70,12 +52,8 @@ contract VaultDiamond { returndatacopy(0, 0, returndatasize()) // return any return value or error back to the caller switch result - case 0 { - revert(0, returndatasize()) - } - default { - return(0, returndatasize()) - } + case 0 { revert(0, returndatasize()) } + default { return(0, returndatasize()) } } } diff --git a/contracts/Vault/facets/DiamondCutFacet.sol b/contracts/Vault/facets/DiamondCutFacet.sol index 0e8beaa..5bc522d 100644 --- a/contracts/Vault/facets/DiamondCutFacet.sol +++ b/contracts/Vault/facets/DiamondCutFacet.sol @@ -13,6 +13,8 @@ import { LibDiamond } from "../libraries/LibDiamond.sol"; import "../libraries/LibLayoutSilo.sol"; import "../libraries/LibStorageBinder.sol"; +import {IVaultDiamond} from "../../interfaces/IVaultDiamond.sol"; + contract DiamondCutFacet is IDiamondCut { /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall @@ -29,10 +31,4 @@ contract DiamondCutFacet is IDiamondCut { if (msg.sender !=IVaultDiamond(address(this)).vaultFactoryDiamond()) revert LibErrors.NoPermissions(); LibDiamond.diamondCut(_diamondCut, _init, _calldata); } - - //temp call made from factory to confirm ownership - function tempOwner() public view returns (address owner_) { - VaultData storage vaultData=LibStorageBinder._bindAndReturnVaultStorage(); - owner_ = vaultData.vaultOwner; - } } diff --git a/contracts/Vault/facets/ModuleManagerFacet.sol b/contracts/Vault/facets/ModuleManagerFacet.sol new file mode 100644 index 0000000..bb0fe0f --- /dev/null +++ b/contracts/Vault/facets/ModuleManagerFacet.sol @@ -0,0 +1,17 @@ +pragma solidity 0.8.4; + +import "../libraries/LibStorageBinder.sol"; +import "../libraries/LibLayoutSilo.sol"; + +contract ModuleManagerFacet { + function getActiveModules() external view returns(string[] memory){ + FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + return fsData.activeModules; + } + + function isActiveModule(string memory _name) external view returns(bool exists_){ + FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + exists_=fsData.activeModule[_name]; + } + +} \ No newline at end of file diff --git a/contracts/Vault/facets/OwnershipFacet.sol b/contracts/Vault/facets/OwnershipFacet.sol new file mode 100644 index 0000000..537a9c0 --- /dev/null +++ b/contracts/Vault/facets/OwnershipFacet.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.4; + +import {LibDiamond} from "../libraries/LibDiamond.sol"; + + +contract OwnershipFacet { + function owner() external view returns (address owner_) { + owner_ = LibDiamond.vaultOwner(); + } +} diff --git a/contracts/Vault/libraries/LibArrayHelpers.sol b/contracts/Vault/libraries/LibArrayHelpers.sol index e0f5dc9..ff7085d 100644 --- a/contracts/Vault/libraries/LibArrayHelpers.sol +++ b/contracts/Vault/libraries/LibArrayHelpers.sol @@ -1,6 +1,6 @@ pragma solidity 0.8.4; -library LibKeepHelpers { +library LibArrayHelpers { function findAddIndex(address _item, address[] memory addressArray) internal pure returns (uint256 i) { for (i; i < addressArray.length; i++) { //using the conventional method since we cannot have duplicate addresses diff --git a/contracts/Vault/libraries/LibStorageBinder.sol b/contracts/Vault/libraries/LibStorageBinder.sol index 8a926eb..4fc1268 100644 --- a/contracts/Vault/libraries/LibStorageBinder.sol +++ b/contracts/Vault/libraries/LibStorageBinder.sol @@ -12,7 +12,7 @@ import "../facets/DMSFacet.sol"; //~(keccak256(abi.encode(slot,200))) library LibStorageBinder { - bytes32 constant SLOT_SALT = keccak256(type(LibKeep).creationCode); + bytes32 constant SLOT_SALT = keccak256('storage_offset_salt'); function _getStorageSlot(string memory _facetName1) internal @@ -28,15 +28,15 @@ library LibStorageBinder { ) internal pure returns (bytes32 slot) { slot = keccak256(bytes(abi.encode(_facetName1, _facetName2))); } - function _getStorageSlot( - string memory _facetName1, - string memory _facetName2, - string memory _facetName3, - string memory _facetName4, - string memory _facetName5 - ) internal pure returns (bytes32 slot) { - slot = keccak256(bytes(abi.encode(_facetName1, _facetName2,_facetName3,_facetName4,_facetName5))); - } + // function _getStorageSlot( + // string memory _facetName1, + // string memory _facetName2, + // string memory _facetName3, + // string memory _facetName4, + // string memory _facetName5 + // ) internal pure returns (bytes32 slot) { + // slot = keccak256(bytes(abi.encode(_facetName1, _facetName2,_facetName3,_facetName4,_facetName5))); + // } function _bindAndReturnFacetStorage() internal diff --git a/contracts/VaultFactory/VaultFactoryDiamond.sol b/contracts/VaultFactory/VaultFactoryDiamond.sol index 71b6a18..c2d5b60 100644 --- a/contracts/VaultFactory/VaultFactoryDiamond.sol +++ b/contracts/VaultFactory/VaultFactoryDiamond.sol @@ -13,7 +13,7 @@ pragma solidity ^0.8.0; import {LibFactoryDiamond} from "./libraries/LibFactoryDiamond.sol"; import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; -import "./libraries/LibAppStorage.sol"; +import "./libraries/LibFactoryAppStorage.sol"; contract VaultFactoryDiamond { constructor(address _contractOwner, address _diamondCutFacet) payable { @@ -31,29 +31,7 @@ contract VaultFactoryDiamond { LibFactoryDiamond.diamondCut(cut, address(0), ""); } - function setAddresses(address[] calldata _addresses) external { - LibFactoryDiamond.enforceIsContractOwner(); - FactoryAppStorage storage s = LibAppStorage.factoryAppStorage(); - s.diamondCutFacet = _addresses[0]; - s.erc20Facet = _addresses[1]; - s.erc721Facet = _addresses[2]; - s.erc1155Facet = _addresses[3]; - s.diamondLoupeFacet = _addresses[4]; - s.vaultFacet = _addresses[5]; - s.slotChecker=_addresses[6]; - } - function setSelectors(bytes4[][] calldata _selectors) external { - LibFactoryDiamond.enforceIsContractOwner(); - FactoryAppStorage storage fs = LibAppStorage.factoryAppStorage(); - assert(_selectors.length == 6); - fs.ERC20SELECTORS = _selectors[0]; - fs.ERC721SELECTORS = _selectors[1]; - fs.ERC1155SELECTORS = _selectors[2]; - fs.DIAMONDLOUPEFACETSELECTORS = _selectors[3]; - fs.VAULTFACETSELECTORS = _selectors[4]; - fs.SLOTCHECKERSELECTORS = _selectors[5]; - } function owner() public view returns (address owner_) { LibFactoryDiamond.DiamondStorage storage ds = LibFactoryDiamond.diamondStorage(); diff --git a/contracts/VaultFactory/facets/ModuleupgraderFacet.sol b/contracts/VaultFactory/facets/ModuleupgraderFacet.sol new file mode 100644 index 0000000..6489dd1 --- /dev/null +++ b/contracts/VaultFactory/facets/ModuleupgraderFacet.sol @@ -0,0 +1,24 @@ + +// SPDX-License-Identifier: MIT +pragma solidity 0.8.4; + +import {StorageLayout} from "../libraries/LibFactoryAppStorage.sol"; +import {LibModuleUpgrades} from "../libraries/LibModuleUpgrades.sol"; + +//Modules are atomic upgrades made to existing vaults +//They consist of at least 1 facet,1 master storage layout and a master slot position +contract ModuleUpgraderFacet is StorageLayout{ + +function upgradeVaultWithModule(string calldata _moduleName,address _vault) external{ + //do create3 checks here + //upgrade vault +LibModuleUpgrades._upgradeVaultWithModule(_moduleName,_vault); +} + +function downgradeVaultWithModule(string calldata _moduleName,address _vault) external{ + //do create3 checks here + //upgrade vault +LibModuleUpgrades._downgradeVaultWithModule(_moduleName,_vault); +} + +} \ No newline at end of file diff --git a/contracts/VaultFactory/facets/VaultSpawnerFacet.sol b/contracts/VaultFactory/facets/VaultSpawnerFacet.sol index 765bce7..e79e28f 100644 --- a/contracts/VaultFactory/facets/VaultSpawnerFacet.sol +++ b/contracts/VaultFactory/facets/VaultSpawnerFacet.sol @@ -4,89 +4,34 @@ import "../../Vault/VaultDiamond.sol"; import "../../Vault/libraries/LibDMS.sol"; import "../../interfaces/IVaultDiamond.sol"; -import "../../interfaces/IDiamondCut.sol"; +import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; import "../../interfaces/IVaultFacet.sol"; +import {FactoryAppStorage,StorageLayout} from "../libraries/LibFactoryAppStorage.sol"; + contract VaultSpawnerFacet is StorageLayout { - event VaultCreated(address indexed owner, address indexed backup, uint256 indexed startingBalance, uint256 vaultID); + event VaultCreated(address indexed owner,uint256 indexed startingBalance, uint256 vaultID); error BackupAddressError(); function createVault( - address[] calldata _inheritors, - uint256[] calldata _weiShare, - uint256 _startingBal, - address _backupAddress - ) - external - payable - returns (address addr) - { - if (_backupAddress == msg.sender) { - revert BackupAddressError(); - } + address _vaultOwner, + uint256 _startingBal + ) external payable returns (address addr) { if (_startingBal > 0) { assert(_startingBal == msg.value); } - assert(_inheritors.length == _weiShare.length); //spawn contract - bytes memory code = type(VaultDiamond).creationCode; - bytes32 entropy = keccak256(abi.encode(msg.sender, block.timestamp, fs.VAULTID)); - assembly { - addr := create2(0, add(code, 0x20), mload(code), entropy) - if iszero(extcodesize(addr)) { revert(0, 0) } - } - //init diamond with diamondCut facet - //insert a constant cut facet...modular and reusable across diamonds - IVaultDiamond(addr).init(fs.diamondCutFacet, _backupAddress); - //assert diamond owner - //confirm for EOA auth in same call frame - assert(IVaultDiamond(addr).tempOwner() == tx.origin); - //deposit startingBal - (bool success,) = addr.call{value: _startingBal}(""); - assert(success); + bytes32 entropy = keccak256(abi.encode(_vaultOwner, fs.VAULTID)); - //proceed to upgrade new diamond with default facets - IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](6); - cut[0] = IDiamondCut.FacetCut({ - facetAddress: fs.erc20Facet, - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: fs.ERC20SELECTORS - }); - cut[1] = IDiamondCut.FacetCut({ - facetAddress: fs.erc721Facet, - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: fs.ERC721SELECTORS - }); - cut[2] = IDiamondCut.FacetCut({ - facetAddress: fs.erc1155Facet, - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: fs.ERC1155SELECTORS - }); - cut[3] = IDiamondCut.FacetCut({ - facetAddress: fs.diamondLoupeFacet, - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: fs.DIAMONDLOUPEFACETSELECTORS - }); - cut[4] = IDiamondCut.FacetCut({ - facetAddress: fs.vaultFacet, - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: fs.VAULTFACETSELECTORS - }); - - cut[5] = IDiamondCut.FacetCut({ - facetAddress: fs.slotChecker, - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: fs.SLOTCHECKERSELECTORS - }); - //upgrade - IDiamondCut(addr).diamondCut(cut, address(0), ""); - //add inheritors if any - if (_inheritors.length > 0) { - IVaultFacet(addr).addInheritors(_inheritors, _weiShare); - } +//get Selector and Token Module FacetCuts +IDiamondCut.FacetCut[] storage selectorModuleCut=fs.masterModules["Selector"].facetData; +IDiamondCut.FacetCut[] storage tokenModuleCut=fs.masterModules["Token"].facetData; - emit VaultCreated(msg.sender, _backupAddress, _startingBal, fs.VAULTID); + VaultDiamond vDiamond = + new VaultDiamond{salt:entropy,value:_startingBal}(selectorModuleCut,tokenModuleCut,_vaultOwner); + addr = address(vDiamond); + emit VaultCreated(msg.sender, _startingBal, fs.VAULTID); fs.VAULTID++; } } diff --git a/contracts/VaultFactory/libraries/LibAppStorage.sol b/contracts/VaultFactory/libraries/LibAppStorage.sol deleted file mode 100644 index 3519c1a..0000000 --- a/contracts/VaultFactory/libraries/LibAppStorage.sol +++ /dev/null @@ -1,48 +0,0 @@ -pragma solidity 0.8.4; - -import "../../Vault/libraries/LibKeepHelpers.sol"; - -struct FactoryAppStorage { - //master vaultID - uint256 VAULTID; - //mapping(address=>uint[]) userVaults; - - //set during Master Diamond Deployment - //used to upgrade individual vaults - address diamondCutFacet; - address erc20Facet; - address erc721Facet; - address erc1155Facet; - address diamondLoupeFacet; - address vaultFacet; - address slotChecker; - - //facet selector data for spawned vaults - - bytes4[] ERC20SELECTORS; - bytes4[] ERC721SELECTORS; - bytes4[] ERC1155SELECTORS; - bytes4[] DIAMONDLOUPEFACETSELECTORS; - bytes4[] VAULTFACETSELECTORS; - bytes4[] SLOTCHECKERSELECTORS; -} - -library LibAppStorage { - function factoryAppStorage() internal pure returns (FactoryAppStorage storage fs) { - assembly { - fs.slot := 0 - } - } -} - -abstract contract StorageLayout { - FactoryAppStorage internal fs; - - // function removeArray(uint256 _val,address _inheritor) public { - // LibKeepHelpers.removeUint(fs.userVaults[_inheritor],_val); - // } - - // function addArray(uint256 _val,address _inheritor) public { - // LibKeepHelpers.removeUint(fs.userVaults[_inheritor],_val); - // } -} diff --git a/contracts/interfaces/IVaultDiamond.sol b/contracts/interfaces/IVaultDiamond.sol index 288be9b..b7cf799 100644 --- a/contracts/interfaces/IVaultDiamond.sol +++ b/contracts/interfaces/IVaultDiamond.sol @@ -1,7 +1,7 @@ pragma solidity 0.8.4; interface IVaultDiamond { - function init(address _diamondCutFacet, address _backupAddress) external; + function vaultFactoryDiamond() external view returns(address); //via delegatecall on diamond function vaultOwner() external view returns (address); diff --git a/lib/solmate.git b/lib/solmate.git index d155ee8..352e1e9 160000 --- a/lib/solmate.git +++ b/lib/solmate.git @@ -1 +1 @@ -Subproject commit d155ee8d58f96426f57c015b34dee8a410c1eacc +Subproject commit 352e1e91e9deec9f3961a8abc49dab89d560cfe3 From 960e5e9be1cb16e06caeff77ff7def884f6f5534 Mon Sep 17 00:00:00 2001 From: Timidan Date: Wed, 9 Nov 2022 11:09:45 +0100 Subject: [PATCH 2/4] upgrade changes --- contracts/Vault/facets/ModuleManagerFacet.sol | 25 +++++-- contracts/Vault/libraries/LibArrayHelpers.sol | 42 +++++++++--- contracts/Vault/libraries/LibDMSGuards.sol | 16 ++--- contracts/Vault/libraries/LibDiamond.sol | 13 ++-- .../Vault/libraries/LibModuleUpgrades.sol | 67 +++++++++++++++++++ .../facets/ModuleRegistryFacet.sol | 26 +++++-- .../facets/ModuleupgraderFacet.sol | 24 ------- .../libraries/LibModuleRegistry.sol | 34 +++++++++- .../libraries/LibModuleUpgrades.sol | 51 -------------- contracts/interfaces/IModuleData.sol | 2 +- contracts/interfaces/IVaultDiamond.sol | 3 +- contracts/interfaces/IVaultFactory.sol | 12 ++++ foundry.toml | 3 + 13 files changed, 198 insertions(+), 120 deletions(-) create mode 100644 contracts/Vault/libraries/LibModuleUpgrades.sol delete mode 100644 contracts/VaultFactory/facets/ModuleupgraderFacet.sol delete mode 100644 contracts/VaultFactory/libraries/LibModuleUpgrades.sol create mode 100644 contracts/interfaces/IVaultFactory.sol diff --git a/contracts/Vault/facets/ModuleManagerFacet.sol b/contracts/Vault/facets/ModuleManagerFacet.sol index bb0fe0f..5364260 100644 --- a/contracts/Vault/facets/ModuleManagerFacet.sol +++ b/contracts/Vault/facets/ModuleManagerFacet.sol @@ -2,16 +2,27 @@ pragma solidity 0.8.4; import "../libraries/LibStorageBinder.sol"; import "../libraries/LibLayoutSilo.sol"; +import "../libraries/LibModuleUpgrades.sol"; contract ModuleManagerFacet { - function getActiveModules() external view returns(string[] memory){ - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + function getActiveModules() external view returns (string[] memory) { + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); return fsData.activeModules; } - - function isActiveModule(string memory _name) external view returns(bool exists_){ - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); - exists_=fsData.activeModule[_name]; + + function isActiveModule(string memory _name) external view returns (bool exists_) { + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); + exists_ = fsData.activeModule[_name]; } -} \ No newline at end of file + //upgrade + + function upgradeVaultWithModule(string calldata _name) external { + LibModuleUpgrades._upgradeVaultWithModule(_name); + } + + //downgrade + function downgradeVaultWithModule(string calldata _name) external { + LibModuleUpgrades._downgradeVaultWithModule(_name); + } +} diff --git a/contracts/Vault/libraries/LibArrayHelpers.sol b/contracts/Vault/libraries/LibArrayHelpers.sol index ff7085d..227474d 100644 --- a/contracts/Vault/libraries/LibArrayHelpers.sol +++ b/contracts/Vault/libraries/LibArrayHelpers.sol @@ -10,11 +10,7 @@ library LibArrayHelpers { } } - function findUintIndex(uint _item, uint[] memory noArray) - internal - pure - returns (uint256 i) - { + function findUintIndex(uint256 _item, uint256[] memory noArray) internal pure returns (uint256 i) { for (i; i < noArray.length; i++) { if (noArray[i] == _item) { return i; @@ -22,7 +18,33 @@ library LibArrayHelpers { } } - function removeUint(uint[] storage _noArray, uint to) internal { + function findStringIndex(string memory _item, string[] memory stringArray) internal pure returns (uint256 i) { + for (i; i < stringArray.length; i++) { + if (__equalTo__(stringArray[i], _item)) { + return i; + } + } + } + + function __equalTo__(string memory a, string memory b) private pure returns (bool) { + return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)))); + } + + function removeString(string[] storage _stringArray, string memory to) internal { + require(_stringArray.length > 0, "Non-elemented number array"); + uint256 index = findStringIndex(to, _stringArray); + if (_stringArray.length == 1) { + _stringArray.pop(); + } + if (_stringArray.length > 1) { + for (uint256 i = index; i < _stringArray.length - 1; i++) { + _stringArray[i] = _stringArray[i + 1]; + } + _stringArray.pop(); + } + } + + function removeUint(uint256[] storage _noArray, uint256 to) internal { require(_noArray.length > 0, "Non-elemented number array"); uint256 index = findUintIndex(to, _noArray); if (_noArray.length == 1) { @@ -51,8 +73,8 @@ library LibArrayHelpers { } } - function _inUintArray(uint256[] memory _array,uint256 _targ) internal pure returns (bool exists_) { - if(_array.length>0){ + function _inUintArray(uint256[] memory _array, uint256 _targ) internal pure returns (bool exists_) { + if (_array.length > 0) { for (uint256 i; i < _array.length; i++) { if (_targ == _array[i]) { exists_ = true; @@ -61,8 +83,8 @@ library LibArrayHelpers { } } - function _inAddressArray(address[] memory _array,address _targ) internal pure returns (bool exists_) { - if(_array.length>0){ + function _inAddressArray(address[] memory _array, address _targ) internal pure returns (bool exists_) { + if (_array.length > 0) { for (uint256 i; i < _array.length; i++) { if (_targ == _array[i]) { exists_ = true; diff --git a/contracts/Vault/libraries/LibDMSGuards.sol b/contracts/Vault/libraries/LibDMSGuards.sol index caf849b..e3f1e9e 100644 --- a/contracts/Vault/libraries/LibDMSGuards.sol +++ b/contracts/Vault/libraries/LibDMSGuards.sol @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.4; - -import {DMSData,FacetAndSelectorData} from "../libraries/LibLayoutSilo.sol"; +import {DMSData, FacetAndSelectorData} from "../libraries/LibLayoutSilo.sol"; import {LibStorageBinder} from "../libraries/LibStorageBinder.sol"; error NotBackupAddress(); @@ -10,11 +11,10 @@ error HasExpired(); error Claimed(); library LibDMSGuards { - -//check -function _onlyVaultOwnerOrBackup() internal view { + //check + function _onlyVaultOwnerOrBackup() internal view { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); if (msg.sender != vaultData.backupAddress && msg.sender != fsData.vaultOwner) { revert NotOwnerOrBackupAddress(); } @@ -82,6 +82,4 @@ function _onlyVaultOwnerOrBackup() internal view { revert Claimed(); } } - - -} \ No newline at end of file +} diff --git a/contracts/Vault/libraries/LibDiamond.sol b/contracts/Vault/libraries/LibDiamond.sol index d4cfeac..64466bf 100644 --- a/contracts/Vault/libraries/LibDiamond.sol +++ b/contracts/Vault/libraries/LibDiamond.sol @@ -9,6 +9,7 @@ import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; import {FacetAndSelectorData} from "../libraries/LibLayoutSilo.sol"; import "../libraries/LibStorageBinder.sol"; +import "../../interfaces/IVaultDiamond.sol"; library LibDiamond { error InValidFacetCutAction(); @@ -24,15 +25,6 @@ library LibDiamond { error NonEmptyCalldata(); error EmptyCalldata(); error InitCallFailed(); - // bytes32 constant VAULT_STORAGE_POSITION = - // keccak256("diamond.standard.keep.storage"); - - // function vaultStorage() internal pure returns (VaultStorage storage vaultData) { - // bytes32 position = VAULT_STORAGE_POSITION; - // assembly { - // vaultData.slot := position - // } - // } event OwnershipTransferred( address indexed previousOwner, @@ -60,6 +52,9 @@ library LibDiamond { if (msg.sender != LibStorageBinder._bindAndReturnFacetStorage().vaultOwner) revert NotVaultOwner(); } +function vaultFactory() internal view returns(address){ + return IVaultDiamond(address(this)).vaultFactoryDiamond(); +} event DiamondCut( IDiamondCut.FacetCut[] _diamondCut, address _init, diff --git a/contracts/Vault/libraries/LibModuleUpgrades.sol b/contracts/Vault/libraries/LibModuleUpgrades.sol new file mode 100644 index 0000000..dc5e726 --- /dev/null +++ b/contracts/Vault/libraries/LibModuleUpgrades.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.4; + +import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; +import {LibStorageBinder} from "../../Vault/libraries/LibStorageBinder.sol"; +import {IModuleData} from "../../interfaces/IModuleData.sol"; +import {IVaultFactory} from "../../interfaces/IVaultFactory.sol"; +import {FacetAndSelectorData} from "../libraries/LibLayoutSilo.sol"; +import {LibStorageBinder} from "../libraries/LibStorageBinder.sol"; +import {LibDiamond} from "../libraries/LibDiamond.sol"; +import {LibArrayHelpers} from "../libraries/LibArrayHelpers.sol"; + +error ModuleAlreadyInstalled(); +error ModuleNotInstalled(); + +//basically allows vault owners to make atomic module upgrades to their vaults + +library LibModuleUpgrades { + /** + * address _vault* + */ + event VaultUpgraded(string indexed _moduleName); + /** + * address _vault* + */ + event VaultDowngraded(string indexed _moduleName); + + function _upgradeVaultWithModule(string calldata _name) internal { + LibDiamond.enforceIsContractOwner(); + //make sure this module doesn't currently exist in this vault + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); + if (fsData.activeModule[_name]) revert ModuleAlreadyInstalled(); + //get facet data + //no need to check for existence in registry as this will revert if it does not exist + IDiamondCut.FacetCut[] memory facetData = IVaultFactory(LibDiamond.vaultFactory()).getFacetCuts(_name); + //upgrade vault + IDiamondCut(address(this)).diamondCut(facetData, address(0), ""); + + fsData.activeModule[_name] = true; + fsData.activeModules.push(_name); + + emit VaultUpgraded(_name); + //consider gossiping this upgrade to vaultFactory + } + + function _downgradeVaultWithModule(string calldata _name) internal { + LibDiamond.enforceIsContractOwner(); + //make sure this module doesn't currently exist in this vault + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); + if (!fsData.activeModule[_name]) revert ModuleNotInstalled(); + //get facet data + //no need to check for existence in registry as this will revert if it does not exist + IDiamondCut.FacetCut[] memory facetData = IVaultFactory(LibDiamond.vaultFactory()).getFacetCuts(_name); + //upgrade vault + //remove them + for (uint256 i = 0; i < facetData.length; i++) { + facetData[i].action = IDiamondCut.FacetCutAction.Remove; + facetData[i].facetAddress = address(0); + } + //downgrade vault + IDiamondCut(address(this)).diamondCut(facetData, address(0), ""); + fsData.activeModule[_name] = true; + LibArrayHelpers.removeString(fsData.activeModules, _name); + emit VaultDowngraded(_name); + //consider gossiping this downgrade to vaultFactory + } +} diff --git a/contracts/VaultFactory/facets/ModuleRegistryFacet.sol b/contracts/VaultFactory/facets/ModuleRegistryFacet.sol index 6633668..6749ce5 100644 --- a/contracts/VaultFactory/facets/ModuleRegistryFacet.sol +++ b/contracts/VaultFactory/facets/ModuleRegistryFacet.sol @@ -4,10 +4,26 @@ import {StorageLayout} from "../libraries/LibFactoryAppStorage.sol"; import {LibModuleRegistry} from "../libraries/LibModuleRegistry.sol"; import {IModuleData} from "../../interfaces/IModuleData.sol"; -contract ModuleRegistryFacet is StorageLayout{ +import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; +contract ModuleRegistryFacet is StorageLayout { + function addModules(IModuleData.ModuleData[] calldata _modules, string[] calldata _names) external { + LibModuleRegistry._addModules(_modules, _names); + } - function addModules(IModuleData.ModuleData[] calldata _modules, string[] calldata _names) external{ - LibModuleRegistry._addModules(_modules,_names); - } -} \ No newline at end of file + function getModules(string[] calldata _names) external view returns (IModuleData.ModuleData[] memory modules_) { + modules_ = LibModuleRegistry._getModules(_names); + } + + function getModule(string calldata _name) external view returns (IModuleData.ModuleData memory module_) { + module_ = LibModuleRegistry._getModule(_name); + } + + function getFacetCuts(string memory _name) external view returns (IDiamondCut.FacetCut[] memory cuts_) { + cuts_ = LibModuleRegistry._getFacetCuts(_name); + } + + function moduleExists(string calldata _name) external view returns (bool exists_) { + exists_ = LibModuleRegistry._moduleExists(_name); + } +} diff --git a/contracts/VaultFactory/facets/ModuleupgraderFacet.sol b/contracts/VaultFactory/facets/ModuleupgraderFacet.sol deleted file mode 100644 index 6489dd1..0000000 --- a/contracts/VaultFactory/facets/ModuleupgraderFacet.sol +++ /dev/null @@ -1,24 +0,0 @@ - -// SPDX-License-Identifier: MIT -pragma solidity 0.8.4; - -import {StorageLayout} from "../libraries/LibFactoryAppStorage.sol"; -import {LibModuleUpgrades} from "../libraries/LibModuleUpgrades.sol"; - -//Modules are atomic upgrades made to existing vaults -//They consist of at least 1 facet,1 master storage layout and a master slot position -contract ModuleUpgraderFacet is StorageLayout{ - -function upgradeVaultWithModule(string calldata _moduleName,address _vault) external{ - //do create3 checks here - //upgrade vault -LibModuleUpgrades._upgradeVaultWithModule(_moduleName,_vault); -} - -function downgradeVaultWithModule(string calldata _moduleName,address _vault) external{ - //do create3 checks here - //upgrade vault -LibModuleUpgrades._downgradeVaultWithModule(_moduleName,_vault); -} - -} \ No newline at end of file diff --git a/contracts/VaultFactory/libraries/LibModuleRegistry.sol b/contracts/VaultFactory/libraries/LibModuleRegistry.sol index 340ed48..f4adeea 100644 --- a/contracts/VaultFactory/libraries/LibModuleRegistry.sol +++ b/contracts/VaultFactory/libraries/LibModuleRegistry.sol @@ -1,18 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.4; -import "../../interfaces/IDiamondCut.sol"; +import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; import "../../Vault/libraries/LibStorageBinder.sol"; import {LibFactoryDiamond} from "./LibFactoryDiamond.sol"; import {FactoryAppStorage, LibFactoryAppStorage} from "./LibFactoryAppStorage.sol"; import {IModuleData} from "../../interfaces/IModuleData.sol"; error ModuleExists(string moduleName); +error NonExistentModule(string moduleName); - library LibModuleRegistry { - event ModuleAdded(string indexed _name,IModuleData.ModuleData _module); + event ModuleAdded(string indexed _name, IModuleData.ModuleData _module); //allow Proxy Factory admin(multisig) to add modules to Module Registry + function _addModules(IModuleData.ModuleData[] calldata _modules, string[] calldata _names) internal { assert(_modules.length == _names.length); LibFactoryDiamond.enforceIsContractOwner(); @@ -26,4 +27,31 @@ library LibModuleRegistry { } } //to-do _removeModules + + function _getModules(string[] memory _names) internal view returns (IModuleData.ModuleData[] memory modules_) { + modules_ = new IModuleData.ModuleData[](_names.length); + for (uint256 i = 0; i < _names.length; i++) { + modules_[i] = _getModule(_names[i]); + } + } + + function _getModule(string memory _name) internal view returns (IModuleData.ModuleData memory module_) { + FactoryAppStorage storage fs = LibFactoryAppStorage.factoryAppStorage(); + IModuleData.ModuleData storage m = fs.masterModules[_name]; + if (m.facetData.length == 0) revert NonExistentModule(_name); + module_ = m; + } + + function _getFacetCuts(string memory _name) internal view returns (IDiamondCut.FacetCut[] memory cuts_) { + FactoryAppStorage storage fs = LibFactoryAppStorage.factoryAppStorage(); + IModuleData.ModuleData storage m = fs.masterModules[_name]; + if (m.facetData.length == 0) revert NonExistentModule(_name); + cuts_ = fs.masterModules[_name].facetData; + } + + function _moduleExists(string memory _name) internal view returns (bool exists_) { + FactoryAppStorage storage fs = LibFactoryAppStorage.factoryAppStorage(); + IModuleData.ModuleData storage m = fs.masterModules[_name]; + if (m.facetData.length > 0) exists_ = true; + } } diff --git a/contracts/VaultFactory/libraries/LibModuleUpgrades.sol b/contracts/VaultFactory/libraries/LibModuleUpgrades.sol deleted file mode 100644 index 8e4118a..0000000 --- a/contracts/VaultFactory/libraries/LibModuleUpgrades.sol +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.4; - -import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; -import {LibStorageBinder} from "../../Vault/libraries/LibStorageBinder.sol"; -//import {LibLayoutSilo} from "../../Vault/libraries/LibLayoutSilo.sol"; -import {LibFactoryDiamond} from "./LibFactoryDiamond.sol"; -import {FactoryAppStorage, LibFactoryAppStorage} from "./LibFactoryAppStorage.sol"; -import {IModuleData} from "../../interfaces/IModuleData.sol"; - -error NonExistentModule(); -error ModuleAlreadyAdded(); -error ModuleAlreadyRemoved(); -//basically allows vault owners to make atomic module upgrades to their vaults - -library LibModuleUpgrades { - event VaultUpgraded(address _vault, string indexed _moduleName); - event VaultDowngraded(address _vault, string indexed _moduleName); - - function _upgradeVaultWithModule(string calldata _name, address _vault) internal { - //first make sure this module exists in the onchain registry - FactoryAppStorage storage fs = LibFactoryAppStorage.factoryAppStorage(); - if (fs.masterModules[_name].facetData.length == 0) revert NonExistentModule(); - //make sure this module hasn't been added to the vault before - if (IModuleData(_vault).isActiveModule(_name)) revert ModuleAlreadyAdded(); - //get module details - IModuleData.ModuleData storage moduleData = fs.masterModules[_name]; - IDiamondCut.FacetCut[] storage facetCut = moduleData.facetData; - //upgrade vault - IDiamondCut(_vault).diamondCut(facetCut, address(0), ""); - emit VaultUpgraded(_vault, _name); - } - - function _downgradeVaultWithModule(string calldata _name, address _vault) internal { - //first make sure this module exists in the onchain registry - FactoryAppStorage storage fs = LibFactoryAppStorage.factoryAppStorage(); - if (fs.masterModules[_name].facetData.length == 0) revert NonExistentModule(); - //make sure this module has been added to the vault before - if (!IModuleData(_vault).isActiveModule(_name)) revert ModuleAlreadyRemoved(); - //get module details - IModuleData.ModuleData storage moduleData = fs.masterModules[_name]; - IDiamondCut.FacetCut[] storage facetCut = moduleData.facetData; - //remove them - for (uint256 i = 0; i < facetCut.length; i++) { - facetCut[i].action = IDiamondCut.FacetCutAction.Remove; - } - //downgrade vault - IDiamondCut(_vault).diamondCut(facetCut, address(0), ""); - emit VaultDowngraded(_vault, _name); - } -} diff --git a/contracts/interfaces/IModuleData.sol b/contracts/interfaces/IModuleData.sol index 15df21c..aa8bdd3 100644 --- a/contracts/interfaces/IModuleData.sol +++ b/contracts/interfaces/IModuleData.sol @@ -12,7 +12,7 @@ interface IModuleData { //storage location bytes32 slot; //keccak hash of facets involved - bytes32 fileHash; + uint256 timeAdded; //human readable names of facets involved in alphabetical order string[] facetNames; } diff --git a/contracts/interfaces/IVaultDiamond.sol b/contracts/interfaces/IVaultDiamond.sol index b7cf799..3251ef3 100644 --- a/contracts/interfaces/IVaultDiamond.sol +++ b/contracts/interfaces/IVaultDiamond.sol @@ -1,4 +1,5 @@ pragma solidity 0.8.4; +import "../interfaces/IModuleData.sol"; interface IVaultDiamond { function vaultFactoryDiamond() external view returns(address); @@ -6,5 +7,5 @@ interface IVaultDiamond { //via delegatecall on diamond function vaultOwner() external view returns (address); - function tempOwner() external view returns (address owner_); + } diff --git a/contracts/interfaces/IVaultFactory.sol b/contracts/interfaces/IVaultFactory.sol new file mode 100644 index 0000000..239baa8 --- /dev/null +++ b/contracts/interfaces/IVaultFactory.sol @@ -0,0 +1,12 @@ +pragma solidity 0.8.4; + +import {IModuleData} from "../interfaces/IModuleData.sol"; +import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; + +interface IVaultFactory { + function getModules(string[] memory _names) external view returns (IModuleData.ModuleData[] memory modules_); + function getModule(string calldata _name) external view returns (IModuleData.ModuleData memory module_); + + function moduleExists(string calldata _name) external view returns (bool exists_); + function getFacetCuts(string memory _name) external view returns (IDiamondCut.FacetCut[] memory cuts_); +} diff --git a/foundry.toml b/foundry.toml index 876bcef..7a36d1c 100644 --- a/foundry.toml +++ b/foundry.toml @@ -8,6 +8,9 @@ remappings = [ 'eth-gas-reporter/=node_modules/eth-gas-reporter/', 'hardhat/=node_modules/hardhat/', ] +via_ir = false verbosity= 5 ffi=true +optimizer = true +optimizer_runs = 200 # See more config options https://github.com/foundry-rs/foundry/tree/master/config \ No newline at end of file From bdec07d9b6db016b5c0102097c1094e8cef1a79c Mon Sep 17 00:00:00 2001 From: falilah Date: Thu, 10 Nov 2022 10:12:53 +0100 Subject: [PATCH 3/4] test files updated --- contracts/Vault/facets/DiamondCutFacet.sol | 36 +- contracts/Vault/libraries/LibTokens.sol | 358 +++++++---- .../VaultFactory/facets/VaultSpawnerFacet.sol | 37 +- ...ltFacetTests.t.sol => DMSFacetTests.t.sol} | 90 ++- test/DiamondDeployments.sol | 570 ++++++++++-------- test/ERC1155FacetTest.t.sol | 234 ++++--- test/ERC20FacetTest.t.sol | 134 ++-- test/ERC721FacetTest.t.sol | 231 ++++--- test/EtherOpsTests.t.sol | 110 ++-- 9 files changed, 1078 insertions(+), 722 deletions(-) rename test/{VaultFacetTests.t.sol => DMSFacetTests.t.sol} (56%) diff --git a/contracts/Vault/facets/DiamondCutFacet.sol b/contracts/Vault/facets/DiamondCutFacet.sol index 5bc522d..f1c4a80 100644 --- a/contracts/Vault/facets/DiamondCutFacet.sol +++ b/contracts/Vault/facets/DiamondCutFacet.sol @@ -6,29 +6,29 @@ pragma solidity 0.8.4; * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ -import { IDiamondCut } from "../../interfaces/IDiamondCut.sol"; +import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; -import { LibErrors } from "../libraries/LibErrors.sol"; -import { LibDiamond } from "../libraries/LibDiamond.sol"; +import {LibErrors} from "../libraries/LibErrors.sol"; +import {LibDiamond} from "../libraries/LibDiamond.sol"; import "../libraries/LibLayoutSilo.sol"; import "../libraries/LibStorageBinder.sol"; import {IVaultDiamond} from "../../interfaces/IVaultDiamond.sol"; contract DiamondCutFacet is IDiamondCut { - /// @notice Add/replace/remove any number of functions and optionally execute - /// a function with delegatecall - /// @param _diamondCut Contains the facet addresses and function selectors - /// @param _init The address of the contract or facet to execute _calldata - /// @param _calldata A function call, including function selector and arguments - /// _calldata is executed with delegatecall on _init - function diamondCut( - FacetCut[] calldata _diamondCut, - address _init, - bytes calldata _calldata - ) external override { -// restrict upgrades to VaultFactoryDiamond only - if (msg.sender !=IVaultDiamond(address(this)).vaultFactoryDiamond()) revert LibErrors.NoPermissions(); - LibDiamond.diamondCut(_diamondCut, _init, _calldata); - } + /// @notice Add/replace/remove any number of functions and optionally execute + /// a function with delegatecall + /// @param _diamondCut Contains the facet addresses and function selectors + /// @param _init The address of the contract or facet to execute _calldata + /// @param _calldata A function call, including function selector and arguments + /// _calldata is executed with delegatecall on _init + function diamondCut( + FacetCut[] calldata _diamondCut, + address _init, + bytes calldata _calldata + ) external override { + // restrict upgrades to VaultFactoryDiamond only + // if (msg.sender !=IVaultDiamond(address(this)).vaultFactoryDiamond()) revert LibErrors.NoPermissions(); + LibDiamond.diamondCut(_diamondCut, _init, _calldata); + } } diff --git a/contracts/Vault/libraries/LibTokens.sol b/contracts/Vault/libraries/LibTokens.sol index 807a81c..f017f06 100644 --- a/contracts/Vault/libraries/LibTokens.sol +++ b/contracts/Vault/libraries/LibTokens.sol @@ -14,21 +14,40 @@ bytes4 constant ERC1155_ACCEPTED = 0xf23a6e61; bytes4 constant ERC1155_BATCH_ACCEPTED = 0xbc197c81; bytes4 constant ERC721WithCall = 0xb88d4fde; - error InsufficientTokens(); - error NotERC721Owner(); +error InsufficientTokens(); +error NotERC721Owner(); //token deposit events might be deprecated since deposits can occur without any contract triggers for the vault library LibTokens { - event ErrorHandled(address); event ERC20ErrorHandled(address); event ERC721ErrorHandled(address); - event ERC20TokenDeposit(address indexed token, address indexed from, uint256 amount, uint256 vaultID); - event ERC20TokenWithdrawal(address token, uint256 amount, address to, uint256 vaultID); + event ERC20TokenDeposit( + address indexed token, + address indexed from, + uint256 amount, + uint256 vaultID + ); + event ERC20TokenWithdrawal( + address token, + uint256 amount, + address to, + uint256 vaultID + ); - event ERC721TokenDeposit(address indexed token, address indexed from, uint256 tokenID, uint256 vaultID); - event ERC721TokenWIthdrawal(address token, uint256 tokenID, address to, uint256 vaultID); + event ERC721TokenDeposit( + address indexed token, + address indexed from, + uint256 tokenID, + uint256 vaultID + ); + event ERC721TokenWIthdrawal( + address token, + uint256 tokenID, + address to, + uint256 vaultID + ); event ERC1155TokenDeposit( address indexed token, @@ -37,7 +56,13 @@ library LibTokens { uint256 amount, uint256 vaultID ); - event ERC1155TokenWithdrawal(address token, uint256 tokenID, uint256 amount, address to, uint256 vaultID); + event ERC1155TokenWithdrawal( + address token, + uint256 tokenID, + uint256 amount, + address to, + uint256 vaultID + ); event BatchERC1155TokenDeposit( address indexed token, @@ -48,7 +73,10 @@ library LibTokens { ); //ERC20 - function _inputERC20Tokens(address[] calldata _tokenDeps, uint256[] calldata _amounts) internal { + function _inputERC20Tokens( + address[] calldata _tokenDeps, + uint256[] calldata _amounts + ) internal { if (_tokenDeps.length == 0 || _amounts.length == 0) { revert LibErrors.EmptyArray(); } @@ -63,7 +91,12 @@ library LibTokens { success; } catch { if (success) { - emit ERC20TokenDeposit(token, msg.sender, amount, LibDiamond.vaultID()); + emit ERC20TokenDeposit( + token, + msg.sender, + amount, + LibDiamond.vaultID() + ); } else { emit ErrorHandled(token); continue; @@ -74,50 +107,61 @@ library LibTokens { function _inputERC20Token(address _token, uint256 _amount) internal { assert(IERC20(_token).transferFrom(msg.sender, address(this), _amount)); - emit ERC20TokenDeposit(_token, msg.sender, _amount, LibDiamond.vaultID()); + emit ERC20TokenDeposit( + _token, + msg.sender, + _amount, + LibDiamond.vaultID() + ); } function _approveERC20Token( address _spender, address _token, uint256 _amount - ) - internal - { + ) internal { IERC20(_token).approve(_spender, _amount); - //ping if DMS is installed - if(LibModuleManager._isActiveModule("DMS")){ - LibDMS._ping(); -} + //ping if DMS is installed + if (LibModuleManager._isActiveModule("DMS")) { + LibDMS._ping(); + } } - function _withdrawERC20Token(address _token, uint256 _amount, address _to) internal { - uint256 availableTokens; -uint256 currentBalance = IERC20(_token).balanceOf(address(this)); -//check if DMS module is installed -//also ping if DMS is installed -if(LibModuleManager._isActiveModule("DMS")){ - if(currentBalance > LibDMS.getCurrentAllocatedTokens(_token)){ - availableTokens=currentBalance - LibDMS.getCurrentAllocatedTokens(_token); - LibDMS._ping(); -} -else{ - revert InsufficientTokens(); -} -} -else{ - availableTokens=currentBalance; -} + function _withdrawERC20Token( + address _token, + uint256 _amount, + address _to + ) internal { + uint256 availableTokens; + uint256 currentBalance = IERC20(_token).balanceOf(address(this)); + //check if DMS module is installed + //also ping if DMS is installed + uint256 alloc = LibDMS.getCurrentAllocatedTokens(_token); + if (LibModuleManager._isActiveModule("DMS")) { + if (currentBalance > alloc) { + availableTokens = currentBalance - alloc; + LibDMS._ping(); + } else { + revert InsufficientTokens(); + } + } else { + availableTokens = currentBalance; + } bool success; if (currentBalance >= availableTokens) { - if (currentBalance - availableTokens < _amount) { + if (currentBalance - alloc < _amount) { revert InsufficientTokens(); } try IERC20(_token).transfer(_to, _amount) { success; } catch { if (success) { - emit ERC20TokenWithdrawal(_token, _amount, _to, LibDiamond.vaultID()); + emit ERC20TokenWithdrawal( + _token, + _amount, + _to, + LibDiamond.vaultID() + ); } else { emit ERC20ErrorHandled(_token); } @@ -127,8 +171,11 @@ else{ } } - - function _withdrawERC20Tokens(address[] calldata _tokenAdds, uint256[] calldata _amounts, address _to) internal { + function _withdrawERC20Tokens( + address[] calldata _tokenAdds, + uint256[] calldata _amounts, + address _to + ) internal { if (_tokenAdds.length == 0 || _amounts.length == 0) { revert LibErrors.EmptyArray(); } @@ -138,25 +185,22 @@ else{ for (uint256 x; x < _tokenAdds.length; x++) { address token = _tokenAdds[x]; uint256 amount = _amounts[x]; - uint256 currentBalance = IERC20(token).balanceOf(address(this)); - uint256 availableTokens; - if(LibModuleManager._isActiveModule("DMS")){ -uint256 allocated=LibDMS.getCurrentAllocatedTokens(token); - if(currentBalance >allocated ){ - availableTokens=currentBalance - allocated; - LibDMS._ping(); -} -else{ - revert InsufficientTokens(); -} - } - -else{ - availableTokens=currentBalance; -} + uint256 currentBalance = IERC20(token).balanceOf(address(this)); + uint256 availableTokens; + uint256 allocated = LibDMS.getCurrentAllocatedTokens(token); + if (LibModuleManager._isActiveModule("DMS")) { + if (currentBalance > allocated) { + availableTokens = currentBalance - allocated; + LibDMS._ping(); + } else { + revert InsufficientTokens(); + } + } else { + availableTokens = currentBalance; + } bool success; if (currentBalance >= availableTokens) { - if (currentBalance - availableTokens < _amounts[x]) { + if (currentBalance - allocated < _amounts[x]) { revert InsufficientTokens(); } //for other errors caused by malformed tokens @@ -164,7 +208,12 @@ else{ success; } catch { if (success) { - emit ERC20TokenWithdrawal(token, amount, _to, LibDiamond.vaultID()); + emit ERC20TokenWithdrawal( + token, + amount, + _to, + LibDiamond.vaultID() + ); } else { emit ERC20ErrorHandled(token); } @@ -172,52 +221,83 @@ else{ } else { revert InsufficientTokens(); } - - } + } } //ERC721 function _inputERC721Token(address _token, uint256 _tokenID) internal { - IERC721(_token).transferFrom(msg.sender, address(this), _tokenID); - emit ERC721TokenDeposit(_token, msg.sender, _tokenID, LibDiamond.vaultID()); + emit ERC721TokenDeposit( + _token, + msg.sender, + _tokenID, + LibDiamond.vaultID() + ); } function _safeInputERC721Token(address _token, uint256 _tokenID) internal { - IERC721(_token).safeTransferFrom(msg.sender, address(this), _tokenID); - emit ERC721TokenDeposit(_token, msg.sender, _tokenID, LibDiamond.vaultID()); + emit ERC721TokenDeposit( + _token, + msg.sender, + _tokenID, + LibDiamond.vaultID() + ); } - function _safeInputERC721TokenAndCall(address _token, uint256 _tokenID, bytes calldata _data) internal { - - IERC721(_token).safeTransferFrom(msg.sender, address(this), _tokenID, _data); + function _safeInputERC721TokenAndCall( + address _token, + uint256 _tokenID, + bytes calldata _data + ) internal { + IERC721(_token).safeTransferFrom( + msg.sender, + address(this), + _tokenID, + _data + ); } - function _approveERC721Token(address _token, uint256 _tokenID, address _to) internal { - + function _approveERC721Token( + address _token, + uint256 _tokenID, + address _to + ) internal { IERC721(_token).approve(_to, _tokenID); } - function _approveAllERC721Token(address _token, address _to, bool _approved) internal { - + function _approveAllERC721Token( + address _token, + address _to, + bool _approved + ) internal { IERC721(_token).setApprovalForAll(_to, _approved); } - function _withdrawERC721Token(address _token, uint256 _tokenID, address _to) internal { + function _withdrawERC721Token( + address _token, + uint256 _tokenID, + address _to + ) internal { if (IERC721(_token).ownerOf(_tokenID) != address(this)) { revert NotERC721Owner(); } - if(LibModuleManager._isActiveModule("DMS")){ - if(LibDMS._isERC721Allocated(_token,_tokenID)) - revert("UnAllocate Token First"); + if (LibModuleManager._isActiveModule("DMS")) { + if (LibDMS._isERC721Allocated(_token, _tokenID)) + revert("UnAllocate Token First"); LibDMS._ping(); } - try IERC721(_token).safeTransferFrom(address(this), _to, _tokenID) {} - catch { + try + IERC721(_token).safeTransferFrom(address(this), _to, _tokenID) + {} catch { string memory reason; if (bytes(reason).length == 0) { - emit ERC721TokenWIthdrawal(_token, _tokenID, _to, LibDiamond.vaultID()); + emit ERC721TokenWIthdrawal( + _token, + _tokenID, + _to, + LibDiamond.vaultID() + ); } else { emit ERC721ErrorHandled(_token); } @@ -226,60 +306,104 @@ else{ //ERC1155 - function _safeInputERC1155Token(address _token, uint256 _tokenID, uint256 _value) internal { - - IERC1155(_token).safeTransferFrom(msg.sender, address(this), _tokenID, _value, ""); - emit ERC1155TokenDeposit(_token, msg.sender, _tokenID, _value, LibDiamond.vaultID()); + function _safeInputERC1155Token( + address _token, + uint256 _tokenID, + uint256 _value + ) internal { + IERC1155(_token).safeTransferFrom( + msg.sender, + address(this), + _tokenID, + _value, + "" + ); + emit ERC1155TokenDeposit( + _token, + msg.sender, + _tokenID, + _value, + LibDiamond.vaultID() + ); } function _safeBatchInputERC1155Tokens( address _token, uint256[] calldata _tokenIDs, uint256[] calldata _values - ) - internal - { - - IERC1155(_token).safeBatchTransferFrom(msg.sender, address(this), _tokenIDs, _values, ""); - emit BatchERC1155TokenDeposit(_token, msg.sender, _tokenIDs, _values, LibDiamond.vaultID()); + ) internal { + IERC1155(_token).safeBatchTransferFrom( + msg.sender, + address(this), + _tokenIDs, + _values, + "" + ); + emit BatchERC1155TokenDeposit( + _token, + msg.sender, + _tokenIDs, + _values, + LibDiamond.vaultID() + ); } - function _approveAllERC1155Token(address _token, address _to, bool _approved) internal { - + function _approveAllERC1155Token( + address _token, + address _to, + bool _approved + ) internal { IERC1155(_token).setApprovalForAll(_to, _approved); } + function _withdrawERC1155Token( + address _token, + uint256 _tokenID, + uint256 _amount, + address _to + ) internal { + uint256 currentBalance = IERC1155(_token).balanceOf( + address(this), + _tokenID + ); + uint256 availableTokens; + if (LibModuleManager._isActiveModule("DMS")) { + uint256 allocated = LibDMS.getCurrentAllocated1155tokens( + _token, + _tokenID + ); + if (currentBalance > allocated) { + availableTokens = currentBalance - allocated; + LibDMS._ping(); + } + if (currentBalance < _amount) { + revert InsufficientTokens(); + } - function _withdrawERC1155Token(address _token, uint256 _tokenID, uint256 _amount, address _to) internal { - uint256 currentBalance = IERC1155(_token).balanceOf(address(this), _tokenID); - uint256 availableTokens; -if(LibModuleManager._isActiveModule("DMS")){ - uint256 allocated=LibDMS.getCurrentAllocated1155tokens(_token, _tokenID); - if(currentBalance>allocated){ -availableTokens=currentBalance-allocated; -LibDMS._ping(); - } - if (currentBalance < _amount) { - revert InsufficientTokens(); + if (currentBalance - allocated < _amount) { + revert("UnAllocate TokensFirst"); + } + } else { + availableTokens = currentBalance; } - if (currentBalance - allocated < _amount) { - revert("UnAllocate TokensFirst"); + if (availableTokens < _amount) { + revert InsufficientTokens(); } - -} -else{ - availableTokens=currentBalance; -} - -if(availableTokens<_amount){ - revert InsufficientTokens(); -} - - IERC1155(_token).safeTransferFrom(address(this), _to, _tokenID, _amount, ""); - emit ERC1155TokenWithdrawal(_token, _tokenID, _amount, _to, LibDiamond.vaultID()); - + IERC1155(_token).safeTransferFrom( + address(this), + _to, + _tokenID, + _amount, + "" + ); + emit ERC1155TokenWithdrawal( + _token, + _tokenID, + _amount, + _to, + LibDiamond.vaultID() + ); + } } - -} \ No newline at end of file diff --git a/contracts/VaultFactory/facets/VaultSpawnerFacet.sol b/contracts/VaultFactory/facets/VaultSpawnerFacet.sol index e79e28f..5411bc2 100644 --- a/contracts/VaultFactory/facets/VaultSpawnerFacet.sol +++ b/contracts/VaultFactory/facets/VaultSpawnerFacet.sol @@ -7,30 +7,41 @@ import "../../interfaces/IVaultDiamond.sol"; import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; import "../../interfaces/IVaultFacet.sol"; -import {FactoryAppStorage,StorageLayout} from "../libraries/LibFactoryAppStorage.sol"; +import {FactoryAppStorage, StorageLayout} from "../libraries/LibFactoryAppStorage.sol"; contract VaultSpawnerFacet is StorageLayout { - event VaultCreated(address indexed owner,uint256 indexed startingBalance, uint256 vaultID); + event VaultCreated( + address indexed owner, + uint256 indexed startingBalance, + uint256 vaultID + ); error BackupAddressError(); - function createVault( - address _vaultOwner, - uint256 _startingBal - ) external payable returns (address addr) { + function createVault(address _vaultOwner, uint256 _startingBal) + external + payable + returns (address addr) + { if (_startingBal > 0) { assert(_startingBal == msg.value); } //spawn contract bytes32 entropy = keccak256(abi.encode(_vaultOwner, fs.VAULTID)); -//get Selector and Token Module FacetCuts -IDiamondCut.FacetCut[] storage selectorModuleCut=fs.masterModules["Selector"].facetData; -IDiamondCut.FacetCut[] storage tokenModuleCut=fs.masterModules["Token"].facetData; - - VaultDiamond vDiamond = - new VaultDiamond{salt:entropy,value:_startingBal}(selectorModuleCut,tokenModuleCut,_vaultOwner); - addr = address(vDiamond); + //get Selector and Token Module FacetCuts + IDiamondCut.FacetCut[] storage selectorModuleCut = fs + .masterModules["Selector"] + .facetData; + IDiamondCut.FacetCut[] storage tokenModuleCut = fs + .masterModules["Token"] + .facetData; + + VaultDiamond vDiamond = new VaultDiamond{ + salt: entropy, + value: _startingBal + }(selectorModuleCut, tokenModuleCut, _vaultOwner); + addr = address(vDiamond); emit VaultCreated(msg.sender, _startingBal, fs.VAULTID); fs.VAULTID++; } diff --git a/test/VaultFacetTests.t.sol b/test/DMSFacetTests.t.sol similarity index 56% rename from test/VaultFacetTests.t.sol rename to test/DMSFacetTests.t.sol index ea2d827..490022c 100644 --- a/test/VaultFacetTests.t.sol +++ b/test/DMSFacetTests.t.sol @@ -1,10 +1,9 @@ import "./DiamondDeployments.sol"; import "../contracts/Vault/libraries/LibDMS.sol"; -import "../contracts/Vault/facets/VaultFacet.sol"; -contract VaultFacetTest is DDeployments { - function testVaultOperations() public { +contract DMSFacetTest is DDeployments { + function testDMSOperations() public { address depositor1 = mkaddr("depositor1"); //mint some tokens to depositor1 vm.startPrank(depositor1); @@ -37,99 +36,96 @@ contract VaultFacetTest is DDeployments { vm.startPrank(vault1Owner); //test inheritor addition and removal //add another inheritor - v1VaultFacet.addInheritors( + v1dmsFacet.addInheritors( toSingletonAdd(vault1Inheritor2), toSingletonUINT(1000 wei) ); - VaultFacet.VaultInfo memory vInfo = v1VaultFacet.inspectVault(); + + DMSFacet.VaultInfo memory vInfo = v1dmsFacet.inspectVault(); assertEq(vInfo.inheritors.length, 2); //cannot remove a non existent inheritor vm.expectRevert(LibDMS.NotInheritor.selector); - v1VaultFacet.removeInheritors(toSingletonAdd(mkaddr("non-existent"))); + v1dmsFacet.removeInheritors(toSingletonAdd(mkaddr("non-existent"))); //allocate some erc20,erc721 and erc1155 tokens to an inheritor //erc20 - v1VaultFacet.allocateERC20Tokens( + v1dmsFacet.allocateERC20Tokens( address(erc20t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(100e18) ); - //erc721 - v1VaultFacet.allocateERC721Tokens( + // //erc721 + v1dmsFacet.allocateERC721Tokens( address(erc721t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(0) ); - //erc1155 - v1VaultFacet.allocateERC1155Tokens( + // //erc1155 + v1dmsFacet.allocateERC1155Tokens( address(erc1155t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(0), toSingletonUINT(2) ); - //confirm allocations - v1ERC1155Facet.getAllAllocatedERC1155Tokens(vault1Inheritor1); - v1ERC20Facet.getAllocatedERC20Tokens(vault1Inheritor1); - v1ERC721Facet.getAllocatedERC721Tokens(vault1Inheritor1); + // //confirm allocations + v1dmsFacet.getAllAllocatedERC1155Tokens(vault1Inheritor1); + v1dmsFacet.getAllocatedERC20Tokens(vault1Inheritor1); + v1dmsFacet.getAllocatedERC721Tokens(vault1Inheritor1); - v1VaultFacet.removeInheritors(toSingletonAdd(vault1Inheritor1)); + v1dmsFacet.removeInheritors(toSingletonAdd(vault1Inheritor1)); //re-confirm allocations assertEq( - v1ERC1155Facet - .getAllAllocatedERC1155Tokens(vault1Inheritor1) - .length, + v1dmsFacet.getAllAllocatedERC1155Tokens(vault1Inheritor1).length, 0 ); assertEq( - v1ERC20Facet.getAllocatedERC20Tokens(vault1Inheritor1).length, + v1dmsFacet.getAllocatedERC20Tokens(vault1Inheritor1).length, 0 ); assertEq( - v1ERC721Facet.getAllocatedERC721Tokens(vault1Inheritor1).length, + v1dmsFacet.getAllocatedERC721Tokens(vault1Inheritor1).length, 0 ); - vInfo = v1VaultFacet.inspectVault(); + vInfo = v1dmsFacet.inspectVault(); assertEq(vInfo.inheritors.length, 1); + // //TESTS FOR OWNERSHIP TRANSFER AND BACKUP + address newVault1Owner = mkaddr("NewVault1Owner"); + //transfer ownership to another address + v1dmsFacet.transferOwnership(newVault1Owner); + address newOwner = ownerFacet.owner(); + assertEq(newOwner, newVault1Owner); + vm.stopPrank(); + vm.startPrank(newVault1Owner); -//TESTS FOR OWNERSHIP TRANSFER AND BACKUP -address newVault1Owner=mkaddr('NewVault1Owner'); -//transfer ownership to another address -v1VaultFacet.transferOwnership(newVault1Owner); -address newOwner=v1VaultFacet.vaultOwner(); -assertEq(newOwner,newVault1Owner); -vm.stopPrank(); -vm.startPrank(newVault1Owner); - - - //add inheritor1 again and allocate - v1VaultFacet.addInheritors( + // //add inheritor1 again and allocate + v1dmsFacet.addInheritors( toSingletonAdd(vault1Inheritor1), toSingletonUINT(10000000 wei) ); - //erc20 - v1VaultFacet.allocateERC20Tokens( + // //erc20 + v1dmsFacet.allocateERC20Tokens( address(erc20t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(100e18) ); - //erc721 - v1VaultFacet.allocateERC721Tokens( + // //erc721 + v1dmsFacet.allocateERC721Tokens( address(erc721t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(0) ); - //erc1155 - v1VaultFacet.allocateERC1155Tokens( + // //erc1155 + v1dmsFacet.allocateERC1155Tokens( address(erc1155t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(0), @@ -138,13 +134,13 @@ vm.startPrank(newVault1Owner); vm.stopPrank(); - //attempt to claim - vm.warp(block.timestamp+190 days); + // //attempt to claim + vm.warp(block.timestamp + 190 days); vm.prank(vault1Inheritor1); - v1VaultFacet.claimAllAllocations(); - //ALSO TEST BACKUP-OWNER RECLAMATION HERE -vm.prank(vault1Backup); -v1VaultFacet.claimOwnership(mkaddr('newBackup')); -//There should be a timelock after reclamation before a backup can make vault changes + v1dmsFacet.claimAllAllocations(); + // //ALSO TEST BACKUP-OWNER RECLAMATION HERE + // vm.prank(vault1Backup); + // v1dmsFacet.claimOwnership(mkaddr("newBackup")); + //There should be a timelock after reclamation before a backup can make vault changes } } diff --git a/test/DiamondDeployments.sol b/test/DiamondDeployments.sol index 0e54962..4c7615c 100644 --- a/test/DiamondDeployments.sol +++ b/test/DiamondDeployments.sol @@ -1,185 +1,279 @@ - // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.4; import "forge-std/Test.sol"; +import {IModuleData} from "../contracts/interfaces/IModuleData.sol"; + import "../contracts/Vault/facets/ERC1155Facet.sol"; import "../contracts/Vault/facets/ERC20Facet.sol"; import "../contracts/Vault/facets/ERC721Facet.sol"; +import "../contracts/Vault/facets/EtherFacet.sol"; +import "../contracts/Vault/facets/OwnershipFacet.sol"; + +import "../contracts/Vault/facets/ModuleManagerFacet.sol"; + import "../contracts/Vault/facets/DiamondCutFacet.sol"; import "../contracts/Vault/facets/DiamondLoupeFacet.sol"; -import "../contracts/Vault/facets/VaultFacet.sol"; +import "../contracts/Vault/facets/DMSFacet.sol"; import "../contracts/VaultFactory/facets/VaultSpawnerFacet.sol"; +import "../contracts/VaultFactory/facets/ModuleRegistryFacet.sol"; + import "../contracts/VaultFactory/facets/DiamondCutFactoryFacet.sol"; import "../contracts/VaultFactory/facets/DiamondLoupeFactoryFacet.sol"; import "../contracts/Vault/VaultDiamond.sol"; import "../contracts/VaultFactory/VaultFactoryDiamond.sol"; -import "../contracts/Vault/facets/SlotChecker.sol"; -//import "../contracts/Vault/facets/DiamondCutFacet.sol"; -//import "../contracts/Vault/facets/DiamondLoupeFacet.sol"; +import {ModuleAlreadyInstalled} from "../contracts/Vault/libraries/LibModuleUpgrades.sol"; import "./MockERC1155.sol"; - import "./MockERC20.sol"; - import "./MockERC721.sol"; - - -contract DDeployments is Test,IDiamondCut { -//separate script to deploy all diamonds and expose them for interaction - - - -ERC1155Facet erc1155Facet; -ERC721Facet erc721Facet; -ERC20Facet erc20Facet; -VaultSpawnerFacet spawner; -VaultFacet vFacet; -//VaultDiamond VDiamond; -VaultFactoryDiamond vFactoryDiamond; -DiamondCutFacet dCutFacet; -DiamondLoupeFacet dLoupeFacet; -SlotChecker sChecker; - -DiamondCutFactoryFacet dCutFactoryFacet; -DiamondLoupeFactoryFacet dloupeFactoryFacet; - -//2 instances of eachMocktoken -VaultERC1155Token erc1155t; -VaultERC20Token erc20t; -VaultERC721Token erc721t; - -VaultERC1155Token erc1155t2; -VaultERC20Token erc20t2; -VaultERC721Token erc721t2; - -address vault1; -address vault1Inheritor1; -address vault1Inheritor2; -address vault1Owner; -address vault1Backup; - -//Facet types tied to vaultAddresses -ERC20Facet v1ERC20Facet; -ERC721Facet v1ERC721Facet; -ERC1155Facet v1ERC1155Facet; -VaultFacet v1VaultFacet; - -function setUp() public{ - //deploy Vault facets -erc1155Facet=new ERC1155Facet(); -erc721Facet=new ERC721Facet(); -erc20Facet=new ERC20Facet(); -vFacet=new VaultFacet(); -dCutFacet=new DiamondCutFacet(); -dLoupeFacet=new DiamondLoupeFacet(); - -//just a periphery -sChecker=new SlotChecker(); - -//deploy factory facets -spawner=new VaultSpawnerFacet(); -dCutFactoryFacet=new DiamondCutFactoryFacet(); -dloupeFactoryFacet=new DiamondLoupeFactoryFacet(); -vm.label(address(this),"Factory Lord"); -vFactoryDiamond=new VaultFactoryDiamond(address(this),address(dCutFactoryFacet)); - -//deploy mock tokens -erc1155t=new VaultERC1155Token(); -erc20t=new VaultERC20Token(); -erc721t=new VaultERC721Token(); - -erc1155t2=new VaultERC1155Token(); -erc20t2=new VaultERC20Token(); -erc721t2=new VaultERC721Token(); - - -//upgrade factory diamond -IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](2); - cut[0] = IDiamondCut.FacetCut({ - facetAddress: address(spawner), - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: generateSelectors("VaultSpawnerFacet") - }); - cut[1] = IDiamondCut.FacetCut({ - facetAddress: address(dloupeFactoryFacet), - action: IDiamondCut.FacetCutAction.Add, - functionSelectors: generateSelectors("DiamondLoupeFactoryFacet") - }); - IDiamondCut(address(vFactoryDiamond)).diamondCut(cut, address(0), ""); - - //add facet addresses and selectors to Appstorage - address[] memory vaultFacetAddresses=new address[](7); - vaultFacetAddresses[0]=address(dCutFacet); - vaultFacetAddresses[1]=address(erc20Facet); - vaultFacetAddresses[2]=address(erc721Facet); - vaultFacetAddresses[3]=address(erc1155Facet); - vaultFacetAddresses[4]=address(dLoupeFacet); - vaultFacetAddresses[5]=address(vFacet); - vaultFacetAddresses[6]=address(sChecker); - - vFactoryDiamond.setAddresses(vaultFacetAddresses); - - //set selectors - bytes4[][] memory _selectors=new bytes4[][](6); -_selectors[0]=generateSelectors("ERC20Facet"); -_selectors[1]=generateSelectors("ERC721Facet"); -_selectors[2]=generateSelectors("ERC1155Facet"); -_selectors[3]=generateSelectors("DiamondLoupeFacet"); -_selectors[4]=generateSelectors("VaultFacet"); -_selectors[5]=generateSelectors("SlotChecker"); -vFactoryDiamond.setSelectors(_selectors); - -//create a vault -vault1Inheritor1=mkaddr("inheritor1"); -vault1Inheritor2=mkaddr("vault1Inheritor2"); -vault1Owner=mkaddr("vault1Owner"); -//make sure vault1Owner is tx.origin -vm.prank(address(this),vault1Owner); -vault1Backup=mkaddr("lucky guy"); -vault1=VaultSpawnerFacet(address(vFactoryDiamond)).createVault{value: 1 ether}(toSingletonAdd(vault1Inheritor1),toSingletonUINT(10000),1e18,vault1Backup); - -//export contract types - v1ERC20Facet=ERC20Facet(vault1); - v1ERC721Facet=ERC721Facet(vault1); - v1ERC1155Facet=ERC1155Facet(vault1); - v1VaultFacet=VaultFacet(vault1); - - -//do slot checks -bytes32 i=SlotChecker(vault1).getFacetStorageSlot(); -bytes32 j=SlotChecker(vault1).InterFaceStorageSlot(); -bytes32 k=SlotChecker(vault1).vaultStorageSlot(); -assert(uint256(i)!=uint256(j)); -assert(uint256(k)!=uint256(j)); -assert(uint256(i)!=uint256(k)); - -//check ranges - -unchecked { -assert(stdMath.delta(uint256(i),uint256(j))>100_000); -assert(stdMath.delta(uint256(i),uint256(k))>100_000); -assert(stdMath.delta(uint256(j),uint256(k))>100_000); -//log them out -console.log(stdMath.delta(uint256(i),uint256(j))); -console.log(stdMath.delta(uint256(i),uint256(k))); -console.log(stdMath.delta(uint256(j),uint256(k))); -} - - - -//erc20t.approve(vault1,10000000000000); -// //run a function on the new vault +import "./MockERC20.sol"; +import "./MockERC721.sol"; + +import {IModuleData} from "../contracts/interfaces/IModuleData.sol"; + +contract DDeployments is Test { + //Vault facet Addresss + ERC1155Facet erc1155Facet; + ERC721Facet erc721Facet; + ERC20Facet erc20Facet; + EtherFacet etherFacet; + OwnershipFacet ownerFacet; + // VaultFacet vFacet; + DMSFacet switchFacet; + + //UpgradeVault facet + ModuleManagerFacet managerFacet; + // UpgradeFacetWithModule VUpgraderFacet; + + //Diamond script + DiamondCutFacet dCutFacet; + DiamondLoupeFacet dLoupeFacet; + + //factory + VaultSpawnerFacet spawner; + ModuleRegistryFacet registry; + // ModuleUpgraderFacet FUpgradeFacet; + VaultFactoryDiamond vFactoryDiamond; + + DiamondCutFactoryFacet dCutFactoryFacet; + DiamondLoupeFactoryFacet dloupeFactoryFacet; + + //2 instances of eachMocktoken + VaultERC1155Token erc1155t; + VaultERC20Token erc20t; + VaultERC721Token erc721t; + + VaultERC1155Token erc1155t2; + VaultERC20Token erc20t2; + VaultERC721Token erc721t2; + + address vault1; + address vault1Owner; + address vault1Inheritor1; + address vault1Inheritor2; + + //Facet types tied to vaultAddresses + ERC20Facet v1ERC20Facet; + ERC721Facet v1ERC721Facet; + ERC1155Facet v1ERC1155Facet; + EtherFacet v1EtherFacet; + DMSFacet v1dmsFacet; + + function setUp() public { + //deploy mock tokens + erc1155t = new VaultERC1155Token(); + erc20t = new VaultERC20Token(); + erc721t = new VaultERC721Token(); + + //second tokens + erc1155t2 = new VaultERC1155Token(); + erc20t2 = new VaultERC20Token(); + erc721t2 = new VaultERC721Token(); + + //deploy Vault Token facets + erc1155Facet = new ERC1155Facet(); + erc721Facet = new ERC721Facet(); + erc20Facet = new ERC20Facet(); + etherFacet = new EtherFacet(); + switchFacet = new DMSFacet(); + + //selector facet + dCutFacet = new DiamondCutFacet(); + dLoupeFacet = new DiamondLoupeFacet(); + ownerFacet = new OwnershipFacet(); + managerFacet = new ModuleManagerFacet(); + + //deploy factory facets + spawner = new VaultSpawnerFacet(); + registry = new ModuleRegistryFacet(); + dCutFactoryFacet = new DiamondCutFactoryFacet(); + dloupeFactoryFacet = new DiamondLoupeFactoryFacet(); + vm.label(address(this), "Factory Lord"); + vFactoryDiamond = new VaultFactoryDiamond( + address(this), + address(dCutFactoryFacet) + ); + + //upgrade factory diamond + IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](3); + cut[0] = IDiamondCut.FacetCut({ + facetAddress: address(spawner), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("VaultSpawnerFacet") + }); + cut[1] = IDiamondCut.FacetCut({ + facetAddress: address(dloupeFactoryFacet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("DiamondLoupeFactoryFacet") + }); + + cut[2] = IDiamondCut.FacetCut({ + facetAddress: address(registry), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("ModuleRegistryFacet") + }); + IDiamondCut(address(vFactoryDiamond)).diamondCut(cut, address(0), ""); + + //upgrade Selector Module Vault diamond + + IDiamondCut.FacetCut[] memory selectorCut = new IDiamondCut.FacetCut[]( + 4 + ); + selectorCut[0] = IDiamondCut.FacetCut({ + facetAddress: address(dCutFacet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("DiamondCutFacet") + }); + selectorCut[1] = IDiamondCut.FacetCut({ + facetAddress: address(dLoupeFacet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("DiamondLoupeFacet") + }); + + selectorCut[2] = IDiamondCut.FacetCut({ + facetAddress: address(ownerFacet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("OwnershipFacet") + }); + selectorCut[3] = IDiamondCut.FacetCut({ + facetAddress: address(managerFacet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("ModuleManagerFacet") + }); + + //upgrade Token Module Vault diamond + + IDiamondCut.FacetCut[] memory TokenCut = new IDiamondCut.FacetCut[](4); + + TokenCut[0] = IDiamondCut.FacetCut({ + facetAddress: address(erc20Facet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("ERC20Facet") + }); + TokenCut[1] = IDiamondCut.FacetCut({ + facetAddress: address(erc721Facet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("ERC721Facet") + }); + + TokenCut[2] = IDiamondCut.FacetCut({ + facetAddress: address(erc1155Facet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("ERC1155Facet") + }); + + TokenCut[3] = IDiamondCut.FacetCut({ + facetAddress: address(etherFacet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("EtherFacet") + }); + + IModuleData.ModuleData[] memory data = new IModuleData.ModuleData[](2); + data[0].facetData = selectorCut; + data[1].facetData = TokenCut; + + string[] memory selectorName = new string[](2); + selectorName[0] = "Selector"; + selectorName[1] = "Token"; + //Register Selector and Token Modules in Factory + ModuleRegistryFacet(address(vFactoryDiamond)).addModules( + data, + selectorName + ); + + vault1Owner = mkaddr("vault1Owner"); + vault1Inheritor1 = mkaddr("vault1Inheritor1"); + vault1Inheritor2 = mkaddr("vault1Inheritor2"); + + //make sure vault1Owner is tx.origin + vm.prank(address(this), vault1Owner); + vault1 = VaultSpawnerFacet(address(vFactoryDiamond)).createVault{ + value: 1 ether + }(vault1Owner, 1e18); + + //Register DMS Module in factory diamond + + IDiamondCut.FacetCut[] memory DMSCut = new IDiamondCut.FacetCut[](1); + DMSCut[0] = IDiamondCut.FacetCut({ + facetAddress: address(switchFacet), + action: IDiamondCut.FacetCutAction.Add, + functionSelectors: generateSelectors("DMSFacet") + }); + + IModuleData.ModuleData[] memory DMSdata = new IModuleData.ModuleData[]( + 1 + ); + DMSdata[0].facetData = DMSCut; + + string[] memory DMSselectorName = new string[](1); + DMSselectorName[0] = "DMS"; + + ModuleRegistryFacet(address(vFactoryDiamond)).addModules( + DMSdata, + DMSselectorName + ); + //upgrade DMS Module Vault diamond + vm.prank(vault1Owner); + ModuleManagerFacet(address(vault1)).upgradeVaultWithModule("DMS"); + + //export contract types + v1ERC20Facet = ERC20Facet(vault1); + v1ERC721Facet = ERC721Facet(vault1); + v1ERC1155Facet = ERC1155Facet(vault1); + v1EtherFacet = EtherFacet(vault1); + v1dmsFacet = DMSFacet(vault1); + ownerFacet = OwnershipFacet(vault1); + + vm.prank(vault1Owner); + v1dmsFacet.addInheritors( + toSingletonAdd(vault1Inheritor1), + toSingletonUINT(10000) + ); + } -// erc20t.balanceOf(msg.sender); + function testDefaultModules() public { + // OwnershipFacet(address(vault1)).owner(); -// ERC20Facet(vault1).depositERC20Token(address(erc20t),1000000); -// VaultFacet(vault1).inspectVault(); -// VaultFacet(vault1).allEtherAllocations(); - } + vm.startPrank(vault1Owner); + OwnershipFacet(address(vault1)).owner(); + // upgrade an already existing vault + ModuleManagerFacet(address(vault1)).getActiveModules(); + vm.expectRevert(ModuleAlreadyInstalled.selector); + ModuleManagerFacet(address(vault1)).upgradeVaultWithModule("Selector"); + // downgrade an already exosting vault + ModuleManagerFacet(address(vault1)).downgradeVaultWithModule( + "Selector" + ); + // vm.stopPrank(); + } + function testUpgradeModule() public { + ModuleManagerFacet(address(vault1)).getActiveModules(); + ModuleManagerFacet(address(vault1)).isActiveModule("DMS"); + } - function generateSelectors(string memory _facetName) + function generateSelectors(string memory _facetName) internal returns (bytes4[] memory selectors) { @@ -191,119 +285,61 @@ console.log(stdMath.delta(uint256(j),uint256(k))); selectors = abi.decode(res, (bytes4[])); } - function diamondCut( - FacetCut[] calldata _diamondCut, - address _init, - bytes calldata _calldata - ) external override {} - - function mkaddr(string memory name) public returns (address){ - address addr=address(uint160(uint256(keccak256(abi.encodePacked(name))))); - vm.label(addr,name); + function mkaddr(string memory name) public returns (address) { + address addr = address( + uint160(uint256(keccak256(abi.encodePacked(name)))) + ); + vm.label(addr, name); return addr; } - - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes calldata - ) external virtual returns (bytes4) { - return ERC1155TokenReceiver.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] calldata, - uint256[] calldata, - bytes calldata - ) external virtual returns (bytes4) { - return ERC1155TokenReceiver.onERC1155BatchReceived.selector; - } - - function onERC721Received( - address, - address, - uint256, - bytes calldata - ) external virtual returns (bytes4) { - return ERC721TokenReceiver.onERC721Received.selector; - } - } -//free functions - - function toSingletonUINT(uint256 _no) - - pure - returns (uint256[] memory) - { - uint256[] memory arr = new uint256[](1); - arr[0] = _no; - return arr; - } - - function toSingletonAdd(address _no) - - pure - returns (address[] memory) - { - address[] memory arr = new address[](1); - arr[0] = _no; - return arr; - } - - function toDualUINT(uint256 _no,uint256 _no2) - - pure - returns (uint256[] memory) - { - uint256[] memory arr = new uint256[](2); - arr[0] = _no; - arr[1]=_no2; - return arr; - } - - function toDualAdd(address _no,address _no2) - - pure - returns (address[] memory) - { - address[] memory arr = new address[](2); - arr[0] = _no; - arr[1]=_no2; - return arr; - } - - function toTriUINT(uint256 _no,uint256 _no2,uint256 _no3) - - pure - returns (uint256[] memory) - { - uint256[] memory arr = new uint256[](3); - arr[0] = _no; - arr[1]=_no2; - arr[2]=_no3; - return arr; - } +function toSingletonUINT(uint256 _no) pure returns (uint256[] memory) { + uint256[] memory arr = new uint256[](1); + arr[0] = _no; + return arr; +} - function toTriAddress(address _add,address _add2,address _add3) - - pure - returns (address[] memory) - { - address[] memory arr = new address[](3); - arr[0] = _add; - arr[1]=_add2; - arr[2]=_add3; - return arr; - } +function toSingletonAdd(address _no) pure returns (address[] memory) { + address[] memory arr = new address[](1); + arr[0] = _no; + return arr; +} - +function toDualUINT(uint256 _no, uint256 _no2) pure returns (uint256[] memory) { + uint256[] memory arr = new uint256[](2); + arr[0] = _no; + arr[1] = _no2; + return arr; +} - +function toDualAdd(address _no, address _no2) pure returns (address[] memory) { + address[] memory arr = new address[](2); + arr[0] = _no; + arr[1] = _no2; + return arr; +} +function toTriUINT( + uint256 _no, + uint256 _no2, + uint256 _no3 +) pure returns (uint256[] memory) { + uint256[] memory arr = new uint256[](3); + arr[0] = _no; + arr[1] = _no2; + arr[2] = _no3; + return arr; +} +function toTriAddress( + address _add, + address _add2, + address _add3 +) pure returns (address[] memory) { + address[] memory arr = new address[](3); + arr[0] = _add; + arr[1] = _add2; + arr[2] = _add3; + return arr; +} diff --git a/test/ERC1155FacetTest.t.sol b/test/ERC1155FacetTest.t.sol index 7bd0503..db1c4fe 100644 --- a/test/ERC1155FacetTest.t.sol +++ b/test/ERC1155FacetTest.t.sol @@ -3,92 +3,152 @@ pragma solidity 0.8.4; import "./DiamondDeployments.sol"; import "../contracts/Vault/libraries/LibDMS.sol"; -import "../contracts/Vault/facets/ERC1155Facet.sol"; - - -contract ERC1155FacetTest is DDeployments{ -address depositor1; - -function testERC1155VaultOperations() public{ -depositor1=mkaddr('depositor1'); - -//mint some tokens to depositor1 -vm.startPrank(depositor1); -//NFT 1 -erc1155t.mint(depositor1,0,2); -erc1155t.mint(depositor1,1,2); -erc1155t.mint(depositor1,2,2); -erc1155t.mint(depositor1,3,2); - -//NFT 2 -erc1155t2.mint(depositor1,0,2); -erc1155t2.mint(depositor1,1,2); -erc1155t2.mint(depositor1,2,2); -erc1155t2.mint(depositor1,3,2); - - -//approve diamond to spend all tokens -erc1155t.setApprovalForAll(vault1,true); -erc1155t2.setApprovalForAll(vault1,true); - -//deposit NFTs singlularly -v1ERC1155Facet.depositERC1155Token(address(erc1155t),0,2); -v1ERC1155Facet.depositERC1155Token(address(erc1155t2),0,2); - -//batch deposit -//make sure a failure does not reverts the whole txn -vm.expectRevert(stdError.arithmeticError -); -v1ERC1155Facet.batchDepositERC1155Tokens(address(erc1155t),toTriUINT(1,2,3),toTriUINT(2,2,5)); - - -//deposit tokens normally -v1ERC1155Facet.batchDepositERC1155Tokens(address(erc1155t),toTriUINT(1,2,3),toTriUINT(2,2,2)); -v1ERC1155Facet.batchDepositERC1155Tokens(address(erc1155t2),toTriUINT(1,2,3),toTriUINT(2,2,2)); - -vm.stopPrank(); - -vm.startPrank(vault1Owner); - -///ALLOCATIONS -//try to allocate a token with overflowing balance -vm.expectRevert(abi.encodeWithSelector(LibDMS.TokenAllocationOverflow.selector,address(erc1155t),1)); -v1VaultFacet.allocateERC1155Tokens(address(erc1155t),toDualAdd(vault1Inheritor1,vault1Inheritor2),toDualUINT(0,1),toDualUINT(3,3)); - -//add inheritor2 -v1VaultFacet.addInheritors(toSingletonAdd(vault1Inheritor2),toSingletonUINT(1000 wei)); - -//allocate normally -//allocating id 0 and 1 -v1VaultFacet.allocateERC1155Tokens(address(erc1155t),toDualAdd(vault1Inheritor1,vault1Inheritor2),toDualUINT(0,1),toDualUINT(2,2)); -v1VaultFacet.allocateERC1155Tokens(address(erc1155t2),toDualAdd(vault1Inheritor1,vault1Inheritor2),toDualUINT(0,1),toDualUINT(2,2)); - - -//allocating id 2 and 3 -v1VaultFacet.allocateERC1155Tokens(address(erc1155t),toDualAdd(vault1Inheritor1,vault1Inheritor2),toDualUINT(2,3),toDualUINT(2,2)); -v1VaultFacet.allocateERC1155Tokens(address(erc1155t2),toDualAdd(vault1Inheritor1,vault1Inheritor2),toDualUINT(2,3),toDualUINT(2,2)); - -//confirm storage -ERC1155Facet.AllAllocatedERC1155Tokens[] memory inheritor1Allocs=v1ERC1155Facet.getAllAllocatedERC1155Tokens(vault1Inheritor1); -ERC1155Facet.AllAllocatedERC1155Tokens[] memory inheritor2Allocs=v1ERC1155Facet.getAllAllocatedERC1155Tokens(vault1Inheritor2); - -//2 tokens allocated -assertEq(inheritor2Allocs.length,2); - -//cannot withdraw allocated tokens -vm.expectRevert('UnAllocate TokensFirst'); -v1ERC1155Facet.withdrawERC1155Token(address(erc1155t2),3,2,depositor1); - -//make sure unallocation removes address completely -//completely unallocating tokenID 3 from inheritor2 -v1VaultFacet.allocateERC1155Tokens(address(erc1155t2),toSingletonAdd(vault1Inheritor2),toSingletonUINT(3),toSingletonUINT(0)); - inheritor2Allocs=v1ERC1155Facet.getAllAllocatedERC1155Tokens(vault1Inheritor2); - assertEq(inheritor2Allocs.length,1); - -//can successfully withdraw now -v1ERC1155Facet.withdrawERC1155Token(address(erc1155t2),3,2,depositor1); - +contract ERC1155FacetTest is DDeployments { + address depositor1; + + function testERC1155VaultOperations() public { + depositor1 = mkaddr("depositor1"); + + //mint some tokens to depositor1 + vm.startPrank(depositor1); + //NFT 1 + erc1155t.mint(depositor1, 0, 2); + erc1155t.mint(depositor1, 1, 2); + erc1155t.mint(depositor1, 2, 2); + erc1155t.mint(depositor1, 3, 2); + + //NFT 2 + erc1155t2.mint(depositor1, 0, 2); + erc1155t2.mint(depositor1, 1, 2); + erc1155t2.mint(depositor1, 2, 2); + erc1155t2.mint(depositor1, 3, 2); + + //approve diamond to spend all tokens + erc1155t.setApprovalForAll(vault1, true); + erc1155t2.setApprovalForAll(vault1, true); + + //deposit NFTs singlularly + v1ERC1155Facet.depositERC1155Token(address(erc1155t), 0, 2); + v1ERC1155Facet.depositERC1155Token(address(erc1155t2), 0, 2); + + //batch deposit + //make sure a failure does not reverts the whole txn + vm.expectRevert(stdError.arithmeticError); + v1ERC1155Facet.batchDepositERC1155Tokens( + address(erc1155t), + toTriUINT(1, 2, 3), + toTriUINT(2, 2, 5) + ); + + //deposit tokens normally + v1ERC1155Facet.batchDepositERC1155Tokens( + address(erc1155t), + toTriUINT(1, 2, 3), + toTriUINT(2, 2, 2) + ); + v1ERC1155Facet.batchDepositERC1155Tokens( + address(erc1155t2), + toTriUINT(1, 2, 3), + toTriUINT(2, 2, 2) + ); + + vm.stopPrank(); + + vm.startPrank(vault1Owner); + + ///ALLOCATIONS + //try to allocate a token with overflowing balance + vm.expectRevert( + abi.encodeWithSelector( + LibDMS.TokenAllocationOverflow.selector, + address(erc1155t), + 1 + ) + ); + v1dmsFacet.allocateERC1155Tokens( + address(erc1155t), + toDualAdd(vault1Inheritor1, vault1Inheritor2), + toDualUINT(0, 1), + toDualUINT(3, 3) + ); + + //add inheritor2 + v1dmsFacet.addInheritors( + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(1000 wei) + ); + + //allocate normally + //allocating id 0 and 1 + v1dmsFacet.allocateERC1155Tokens( + address(erc1155t), + toDualAdd(vault1Inheritor1, vault1Inheritor2), + toDualUINT(0, 1), + toDualUINT(2, 2) + ); + v1dmsFacet.allocateERC1155Tokens( + address(erc1155t2), + toDualAdd(vault1Inheritor1, vault1Inheritor2), + toDualUINT(0, 1), + toDualUINT(2, 2) + ); + + //allocating id 2 and 3 + v1dmsFacet.allocateERC1155Tokens( + address(erc1155t), + toDualAdd(vault1Inheritor1, vault1Inheritor2), + toDualUINT(2, 3), + toDualUINT(2, 2) + ); + v1dmsFacet.allocateERC1155Tokens( + address(erc1155t2), + toDualAdd(vault1Inheritor1, vault1Inheritor2), + toDualUINT(2, 3), + toDualUINT(2, 2) + ); + + //confirm storage + DMSFacet.AllAllocatedERC1155Tokens[] + memory inheritor1Allocs = v1dmsFacet.getAllAllocatedERC1155Tokens( + vault1Inheritor1 + ); + DMSFacet.AllAllocatedERC1155Tokens[] + memory inheritor2Allocs = v1dmsFacet.getAllAllocatedERC1155Tokens( + vault1Inheritor2 + ); + + //2 tokens allocated + assertEq(inheritor2Allocs.length, 2); + + //cannot withdraw allocated tokens + vm.expectRevert("UnAllocate TokensFirst"); + v1ERC1155Facet.withdrawERC1155Token( + address(erc1155t2), + 3, + 2, + depositor1 + ); + + //make sure unallocation removes address completely + //completely unallocating tokenID 3 from inheritor2 + v1dmsFacet.allocateERC1155Tokens( + address(erc1155t2), + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(3), + toSingletonUINT(0) + ); + inheritor2Allocs = v1dmsFacet.getAllAllocatedERC1155Tokens( + vault1Inheritor2 + ); + assertEq(inheritor2Allocs.length, 1); + + //can successfully withdraw now + v1ERC1155Facet.withdrawERC1155Token( + address(erc1155t2), + 3, + 2, + depositor1 + ); + } } - -} \ No newline at end of file diff --git a/test/ERC20FacetTest.t.sol b/test/ERC20FacetTest.t.sol index 8b4912b..b24046f 100644 --- a/test/ERC20FacetTest.t.sol +++ b/test/ERC20FacetTest.t.sol @@ -2,8 +2,11 @@ pragma solidity 0.8.4; import "./DiamondDeployments.sol"; import "../contracts/Vault/libraries/LibDiamond.sol"; +import {InsufficientTokens} from "../contracts/Vault/libraries/LibTokens.sol"; import "../contracts/Vault/libraries/LibDMS.sol"; +// import "../contracts/Vault/libraries/LibKeep.sol"; + contract ERC20FacetTest is DDeployments { uint256 snapshotId; address depositor1; @@ -24,19 +27,20 @@ contract ERC20FacetTest is DDeployments { //attempt to deposit 2 tokens //making sure a failure doesn't revert the whole txn v1ERC20Facet.depositERC20Tokens( - toDualAdd(address(erc20t), address(erc20t2)), toDualUINT(maxDepositorBalance + 10, maxDepositorBalance) + toDualAdd(address(erc20t), address(erc20t2)), + toDualUINT(maxDepositorBalance + 10, maxDepositorBalance) ); //confirm deposit assertEq(erc20t2.balanceOf(vault1), maxDepositorBalance); assertEq(erc20t.balanceOf(vault1), 0); - //finally deposit properly + // finally deposit properly v1ERC20Facet.depositERC20Token(address(erc20t), maxDepositorBalance); assertEq(erc20t.balanceOf(vault1), maxDepositorBalance); - //withdraw some erc20 tokens - //you have to be the owner + // withdraw some erc20 tokens + // you have to be the owner vm.expectRevert(LibDiamond.NotVaultOwner.selector); v1ERC20Facet.withdrawERC20Token(address(erc20t), 10e18, depositor1); vm.stopPrank(); @@ -46,9 +50,11 @@ contract ERC20FacetTest is DDeployments { uint256 v1erc20BalanceT1 = erc20t.balanceOf(vault1); uint256 v1erc20BalanceT2 = erc20t2.balanceOf(vault1); vm.startPrank(vault1Owner); - vm.expectRevert(LibDMS.InsufficientTokens.selector); + vm.expectRevert(InsufficientTokens.selector); v1ERC20Facet.batchWithdrawERC20Token( - toDualAdd(address(erc20t), address(erc20t2)), toDualUINT(v1erc20BalanceT1, v1erc20BalanceT2 + 10), depositor1 + toDualAdd(address(erc20t), address(erc20t2)), + toDualUINT(v1erc20BalanceT1, v1erc20BalanceT2 + 10), + depositor1 ); //withdraw normally @@ -63,61 +69,121 @@ contract ERC20FacetTest is DDeployments { assertEq(erc20t2.balanceOf(vault1), 0); assertEq(erc20t.balanceOf(vault1), maxDepositorBalance - 10e18); + ////ADD INHERITORS ///ALLOCATIONS - //Allocating a non-existent token - vm.expectRevert(abi.encodeWithSelector(LibDMS.TokenAllocationOverflow.selector, address(erc20t2), 100e18)); - v1VaultFacet.allocateERC20Tokens(address(erc20t2), toSingletonAdd(vault1Inheritor1), toSingletonUINT(100e18)); + // Allocating a non-existent token + vm.expectRevert( + abi.encodeWithSelector( + LibDMS.TokenAllocationOverflow.selector, + address(erc20t2), + 100e18 + ) + ); + v1dmsFacet.allocateERC20Tokens( + address(erc20t2), + toSingletonAdd(vault1Inheritor1), + toSingletonUINT(100e18) + ); - //Allocating to a non-inheritor + // Allocating to a non-inheritor vm.expectRevert(LibDMS.NotInheritor.selector); - v1VaultFacet.allocateERC20Tokens(address(erc20t2), toSingletonAdd(vault1Inheritor2), toSingletonUINT(100e18)); + v1dmsFacet.allocateERC20Tokens( + address(erc20t2), + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(100e18) + ); - //add inheritor 2 - v1VaultFacet.addInheritors(toSingletonAdd(vault1Inheritor2), toSingletonUINT(1000 wei)); + // add inheritor 2 + v1dmsFacet.addInheritors( + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(1000 wei) + ); //Allocate normally //Allocate all token T1 present in vault 1 v1erc20BalanceT1 = erc20t.balanceOf(vault1); - v1VaultFacet.allocateERC20Tokens( - address(erc20t), toSingletonAdd(vault1Inheritor2), toSingletonUINT(v1erc20BalanceT1) + v1dmsFacet.allocateERC20Tokens( + address(erc20t), + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(v1erc20BalanceT1) ); //try to allocate token T1 to the first inheritor //should overflow - vm.expectRevert(abi.encodeWithSelector(LibDMS.TokenAllocationOverflow.selector, address(erc20t), 50e18)); - v1VaultFacet.allocateERC20Tokens(address(erc20t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(50e18)); + vm.expectRevert( + abi.encodeWithSelector( + LibDMS.TokenAllocationOverflow.selector, + address(erc20t), + 50e18 + ) + ); + v1dmsFacet.allocateERC20Tokens( + address(erc20t), + toSingletonAdd(vault1Inheritor1), + toSingletonUINT(50e18) + ); //free up 50 tokens from inheritor2 by unallocating them - uint256 inheritor2T1Alloc = v1ERC20Facet.inheritorERC20TokenAllocation(vault1Inheritor2, address(erc20t)); - v1VaultFacet.allocateERC20Tokens( - address(erc20t), toSingletonAdd(vault1Inheritor2), toSingletonUINT(inheritor2T1Alloc - 50e18) + uint256 inheritor2T1Alloc = v1dmsFacet.inheritorERC20TokenAllocation( + vault1Inheritor2, + address(erc20t) + ); + v1dmsFacet.allocateERC20Tokens( + address(erc20t), + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(inheritor2T1Alloc - 50e18) ); //allocate to inheritor1 normally now - v1VaultFacet.allocateERC20Tokens(address(erc20t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(50e18)); + v1dmsFacet.allocateERC20Tokens( + address(erc20t), + toSingletonAdd(vault1Inheritor1), + toSingletonUINT(50e18) + ); - //confirm allocation - assertEq(v1ERC20Facet.inheritorERC20TokenAllocation(vault1Inheritor1, address(erc20t)), 50e18); + // confirm allocation + assertEq( + v1dmsFacet.inheritorERC20TokenAllocation( + vault1Inheritor1, + address(erc20t) + ), + 50e18 + ); - //vault owner cannot withdraw any T1 tokens - vm.expectRevert(LibDMS.InsufficientTokens.selector); - v1ERC20Facet.withdrawERC20Token(address(erc20t), v1erc20BalanceT1, depositor1); + // //vault owner cannot withdraw any T1 tokens + vm.expectRevert(InsufficientTokens.selector); + v1ERC20Facet.withdrawERC20Token( + address(erc20t), + v1erc20BalanceT1, + depositor1 + ); //unallocate from an inheritor to free up some tokens - inheritor2T1Alloc = v1ERC20Facet.inheritorERC20TokenAllocation(vault1Inheritor2, address(erc20t)); - v1VaultFacet.allocateERC20Tokens( - address(erc20t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(inheritor2T1Alloc - 20e18) + inheritor2T1Alloc = v1dmsFacet.inheritorERC20TokenAllocation( + vault1Inheritor2, + address(erc20t) + ); + v1dmsFacet.allocateERC20Tokens( + address(erc20t), + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(inheritor2T1Alloc - 20e18) ); - //withdraw all free tokens - uint256 unall = v1ERC20Facet.getUnallocatedTokens(address(erc20t)); + // //withdraw all free tokens + uint256 unall = v1dmsFacet.getUnallocatedTokens(address(erc20t)); v1ERC20Facet.withdrawERC20Token(address(erc20t), unall, depositor1); - //vault T1 balance should now be made up of all inheritor allocations ONLY - uint256 inheritor1T1Alloc = v1ERC20Facet.inheritorERC20TokenAllocation(vault1Inheritor1, address(erc20t)); - inheritor2T1Alloc = v1ERC20Facet.inheritorERC20TokenAllocation(vault1Inheritor2, address(erc20t)); + // //vault T1 balance should now be made up of all inheritor allocations ONLY + uint256 inheritor1T1Alloc = v1dmsFacet.inheritorERC20TokenAllocation( + vault1Inheritor1, + address(erc20t) + ); + inheritor2T1Alloc = v1dmsFacet.inheritorERC20TokenAllocation( + vault1Inheritor2, + address(erc20t) + ); v1erc20BalanceT1 = erc20t.balanceOf(vault1); assertEq(v1erc20BalanceT1, inheritor1T1Alloc + inheritor2T1Alloc); } diff --git a/test/ERC721FacetTest.t.sol b/test/ERC721FacetTest.t.sol index fc91826..2a90849 100644 --- a/test/ERC721FacetTest.t.sol +++ b/test/ERC721FacetTest.t.sol @@ -1,98 +1,143 @@ pragma solidity 0.8.4; import "./DiamondDeployments.sol"; - +import "../contracts/Vault/libraries/LibDiamond.sol"; +import {InsufficientTokens} from "../contracts/Vault/libraries/LibTokens.sol"; import "../contracts/Vault/libraries/LibDMS.sol"; -import "../contracts/Vault/facets/ERC721Facet.sol"; - - -contract ERC721FacetTest is DDeployments{ -address depositor1; - -function testERC721VaultOperations() public{ -depositor1=mkaddr('depositor1'); - -//mint some tokens to depositor1 -vm.startPrank(depositor1); -//NFT 1 -erc721t.mint(depositor1,0); -erc721t.mint(depositor1,1); -erc721t.mint(depositor1,2); -erc721t.mint(depositor1,3); - -//NFT 2 -erc721t2.mint(depositor1,0); -erc721t2.mint(depositor1,1); -erc721t2.mint(depositor1,2); -erc721t2.mint(depositor1,3); - - -//approve diamond to spend all tokens -erc721t.setApprovalForAll(vault1,true); -erc721t2.setApprovalForAll(vault1,true); - - -// deposit multiple tokens -v1ERC721Facet.depositERC721Tokens(address(erc721t),toTriUINT(0,1,2)); -v1ERC721Facet.depositERC721Tokens(address(erc721t2),toTriUINT(0,1,2)); - -//confirm deposit -assertEq(erc721t.balanceOf(vault1),3); -assertEq(erc721t2.balanceOf(vault1),3); - -vm.stopPrank(); -vm.startPrank(vault1Owner); - - -//ALLOCATIONS -//trying to allocate a non existent token should not revert the whole txn -v1VaultFacet.allocateERC721Tokens(address(erc721t),toSingletonAdd(vault1Inheritor1),toSingletonUINT(9)); - -//trying to allocate a token not owned by the vault should not revert the whole txn -v1VaultFacet.allocateERC721Tokens(address(erc721t),toDualAdd(vault1Inheritor1,vault1Inheritor1),toDualUINT(0,3)); - -//confirm storage -ERC721Facet.AllocatedERC721Tokens[] memory vault1Inheritor1Alloc= v1ERC721Facet.getAllocatedERC721Tokens(vault1Inheritor1); -assertEq(vault1Inheritor1Alloc[0].token,address(erc721t)); -assertEq(vault1Inheritor1Alloc[0].tokenIDs[0],0); - -//cannot withdraw an allocated NFT -vm.expectRevert("UnAllocate Token First"); -v1ERC721Facet.withdrawERC721Token(address(erc721t),0,vault1Owner); - -//add inheritor2 -v1VaultFacet.addInheritors(toSingletonAdd(vault1Inheritor2),toSingletonUINT(1000 wei)); - -//can easily reallocate tokens to inheritor2 -v1VaultFacet.allocateERC721Tokens(address(erc721t),toSingletonAdd(vault1Inheritor2),toSingletonUINT(0)); - -//confirm storage -ERC721Facet.AllocatedERC721Tokens[] memory vault1Inheritor2Alloc= v1ERC721Facet.getAllocatedERC721Tokens(vault1Inheritor2); -assertEq(vault1Inheritor2Alloc[0].token,address(erc721t)); -assertEq(vault1Inheritor2Alloc[0].tokenIDs[0],0); - -//make sure token is unallocated from previous inheritor -vault1Inheritor1Alloc= v1ERC721Facet.getAllocatedERC721Tokens(vault1Inheritor1); -assertEq(vault1Inheritor1Alloc.length,0); - - -//unallocate and withdraw -v1VaultFacet.allocateERC721Tokens(address(erc721t),toSingletonAdd(address(0)),toSingletonUINT(0)); -assertEq(v1ERC721Facet.getAllocatedERC721TokenIds(vault1Inheritor2,address(erc721t)).length,0); - //withdraw the token -v1ERC721Facet.withdrawERC721Token(address(erc721t),0,vault1Owner); -//confirm ownership -assertEq(erc721t.ownerOf(0),vault1Owner); - -//cannot allocate to non existent inheritor -vm.expectRevert(LibDMS.NotInheritor.selector); -v1VaultFacet.allocateERC721Tokens(address(erc721t2),toSingletonAdd(mkaddr('noninheritor')),toSingletonUINT(1)); - -//mass allocate tokens -v1VaultFacet.allocateERC721Tokens(address(erc721t2),toTriAddress(vault1Inheritor2,vault1Inheritor2,vault1Inheritor2),toTriUINT(0,1,2)); - -//double check storage -vault1Inheritor2Alloc= v1ERC721Facet.getAllocatedERC721Tokens(vault1Inheritor2); -assertEq(vault1Inheritor2Alloc[0].tokenIDs.length,3); -}} \ No newline at end of file +contract ERC721FacetTest is DDeployments { + address depositor1; + + function testERC721VaultOperations() public { + depositor1 = mkaddr("depositor1"); + + //mint some tokens to depositor1 + vm.startPrank(depositor1); + //NFT 1 + erc721t.mint(depositor1, 0); + erc721t.mint(depositor1, 1); + erc721t.mint(depositor1, 2); + erc721t.mint(depositor1, 3); + + //NFT 2 + erc721t2.mint(depositor1, 0); + erc721t2.mint(depositor1, 1); + erc721t2.mint(depositor1, 2); + erc721t2.mint(depositor1, 3); + + //approve diamond to spend all tokens + erc721t.setApprovalForAll(vault1, true); + erc721t2.setApprovalForAll(vault1, true); + + // deposit multiple tokens + v1ERC721Facet.depositERC721Tokens(address(erc721t), toTriUINT(0, 1, 2)); + v1ERC721Facet.depositERC721Tokens( + address(erc721t2), + toTriUINT(0, 1, 2) + ); + + //confirm deposit + assertEq(erc721t.balanceOf(vault1), 3); + assertEq(erc721t2.balanceOf(vault1), 3); + + vm.stopPrank(); + vm.startPrank(vault1Owner); + + // //ALLOCATIONS + // //trying to allocate a non existent token should not revert the whole txn + v1dmsFacet.allocateERC721Tokens( + address(erc721t), + toSingletonAdd(vault1Inheritor1), + toSingletonUINT(9) + ); + + // //trying to allocate a token not owned by the vault should not revert the whole txn + v1dmsFacet.allocateERC721Tokens( + address(erc721t), + toDualAdd(vault1Inheritor1, vault1Inheritor1), + toDualUINT(0, 3) + ); + + // //confirm storage + DMSFacet.AllocatedERC721Tokens[] + memory vault1Inheritor1Alloc = v1dmsFacet.getAllocatedERC721Tokens( + vault1Inheritor1 + ); + assertEq(vault1Inheritor1Alloc[0].token, address(erc721t)); + assertEq(vault1Inheritor1Alloc[0].tokenIDs[0], 0); + + // //cannot withdraw an allocated NFT + vm.expectRevert("UnAllocate Token First"); + v1ERC721Facet.withdrawERC721Token(address(erc721t), 0, vault1Owner); + + // //add inheritor2 + v1dmsFacet.addInheritors( + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(1000 wei) + ); + + // //can easily reallocate tokens to inheritor2 + v1dmsFacet.allocateERC721Tokens( + address(erc721t), + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(0) + ); + v1dmsFacet.allocateERC721Tokens( + address(erc721t), + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(0) + ); + + // //confirm storage + DMSFacet.AllocatedERC721Tokens[] + memory vault1Inheritor2Alloc = v1dmsFacet.getAllocatedERC721Tokens( + vault1Inheritor2 + ); + assertEq(vault1Inheritor2Alloc[0].token, address(erc721t)); + assertEq(vault1Inheritor2Alloc[0].tokenIDs[0], 0); + + // //make sure token is unallocated from previous inheritor + vault1Inheritor1Alloc = v1dmsFacet.getAllocatedERC721Tokens( + vault1Inheritor1 + ); + assertEq(vault1Inheritor1Alloc.length, 0); + + // //unallocate and withdraw + v1dmsFacet.allocateERC721Tokens( + address(erc721t), + toSingletonAdd(address(0)), + toSingletonUINT(0) + ); + assertEq( + v1dmsFacet + .getAllocatedERC721TokenIds(vault1Inheritor2, address(erc721t)) + .length, + 0 + ); + // //withdraw the token + v1ERC721Facet.withdrawERC721Token(address(erc721t), 0, vault1Owner); + // //confirm ownership + assertEq(erc721t.ownerOf(0), vault1Owner); + + // //cannot allocate to non existent inheritor + vm.expectRevert((LibDMS.NotInheritor.selector)); + v1dmsFacet.allocateERC721Tokens( + address(erc721t2), + toSingletonAdd(mkaddr("noninheritor")), + toSingletonUINT(1) + ); + + // //mass allocate tokens + v1dmsFacet.allocateERC721Tokens( + address(erc721t2), + toTriAddress(vault1Inheritor2, vault1Inheritor2, vault1Inheritor2), + toTriUINT(0, 1, 2) + ); + + // //double check storage + vault1Inheritor2Alloc = v1dmsFacet.getAllocatedERC721Tokens( + vault1Inheritor2 + ); + assertEq(vault1Inheritor2Alloc[0].tokenIDs.length, 3); + } +} diff --git a/test/EtherOpsTests.t.sol b/test/EtherOpsTests.t.sol index 7b99295..1b265d8 100644 --- a/test/EtherOpsTests.t.sol +++ b/test/EtherOpsTests.t.sol @@ -1,61 +1,79 @@ pragma solidity 0.8.4; import "./DiamondDeployments.sol"; -import "../contracts/Vault/libraries/LibDiamond.sol"; +// import "../contracts/Vault/libraries/LibDiamond.sol"; import "../contracts/Vault/libraries/LibDMS.sol"; +import "../contracts/Vault/libraries/LibEther.sol"; -contract EtherOpsTest is DDeployments{ -// struct VaultFacet.AllInheritorEtherAllocs { -// address inheritor; -// uint256 weiAlloc; -// } +contract EtherOpsTests is DDeployments { + // struct VaultFacet.AllInheritorEtherAllocs { + // address inheritor; + // uint256 weiAlloc; + // } + function testAllVaultEtherOperations() public { + vm.startPrank(vault1Owner); -function testAllVaultEtherOperations() public{ -vm.startPrank(vault1Owner); + // get ether allocation data for all inheritors + // only one inheritor currently present + DMSFacet.AllInheritorEtherAllocs[] + memory eAllocs = new DMSFacet.AllInheritorEtherAllocs[](1); + eAllocs[0] = DMSFacet.AllInheritorEtherAllocs({ + inheritor: vault1Inheritor1, + weiAlloc: 10000 + }); + //get data onchain + DMSFacet.AllInheritorEtherAllocs[] memory onchainAllocs = v1dmsFacet + .allEtherAllocations(); + assertEq(onchainAllocs[0].inheritor, eAllocs[0].inheritor); + assertEq(onchainAllocs[0].weiAlloc, eAllocs[0].weiAlloc); + //confirm free ether available for withdrawal + uint256 freeEther = v1dmsFacet.getUnallocatedEther(); + uint256 onchainFreeEther = v1dmsFacet.getUnallocatedEther(); + assertEq(freeEther, onchainFreeEther); -//get ether allocation data for all inheritors -//only one inheritor currently present -VaultFacet.AllInheritorEtherAllocs[] memory eAllocs=new VaultFacet.AllInheritorEtherAllocs[](1); -eAllocs[0]=VaultFacet.AllInheritorEtherAllocs({inheritor:vault1Inheritor1,weiAlloc:10000}); -//get data onchain -VaultFacet.AllInheritorEtherAllocs[] memory onchainAllocs=v1VaultFacet.allEtherAllocations(); -assertEq(onchainAllocs[0].inheritor,eAllocs[0].inheritor); -assertEq(onchainAllocs[0].weiAlloc,eAllocs[0].weiAlloc); + //add another inheritor and allocate some ether + uint256 v1Inheritor2eAlloc = freeEther - 10000000; -//confirm free ether available for withdrawal -uint256 freeEther=v1VaultFacet.getUnallocatedEther(); -uint256 onchainFreeEther=v1VaultFacet.getUnallocatedEther(); -assertEq(freeEther,onchainFreeEther); + //try to allocate more thn available ether + vm.expectRevert( + abi.encodeWithSelector( + LibDMS.EtherAllocationOverflow.selector, + 2 ether - freeEther + ) + ); + v1dmsFacet.addInheritors( + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(2 ether) + ); -//add another inheritor and allocate some ether -uint256 v1Inheritor2eAlloc=freeEther - 10000000; + //allocate normally + v1dmsFacet.addInheritors( + toSingletonAdd(vault1Inheritor2), + toSingletonUINT(v1Inheritor2eAlloc) + ); + uint256 v1Inheritor2EtherAlloc = v1dmsFacet.inheritorEtherAllocation( + vault1Inheritor2 + ); + assertEq(v1Inheritor2EtherAlloc, freeEther - 10000000); -//try to allocate more thn available ether -vm.expectRevert(abi.encodeWithSelector(LibDMS.EtherAllocationOverflow.selector,2 ether -freeEther)); -v1VaultFacet.addInheritors(toSingletonAdd(vault1Inheritor2),toSingletonUINT(2 ether)); + //try to withdraw more than available + freeEther = v1dmsFacet.getUnallocatedEther(); + vm.expectRevert(LibEther.InsufficientEth.selector); + v1EtherFacet.withdrawEther(freeEther + 1000, vault1Owner); -//allocate normally -v1VaultFacet.addInheritors(toSingletonAdd(vault1Inheritor2),toSingletonUINT(v1Inheritor2eAlloc)); -uint256 v1Inheritor2EtherAlloc= v1VaultFacet.inheritorEtherAllocation(vault1Inheritor2); -assertEq(v1Inheritor2EtherAlloc,freeEther - 10000000); - -//try to withdraw more than available -freeEther=v1VaultFacet.getUnallocatedEther(); -vm.expectRevert(LibDMS.InsufficientEth.selector); -v1VaultFacet.withdrawEther(freeEther+1000,vault1Owner); - -//unallocate from both inheritors -//ORDER matters(not really anymore) -v1VaultFacet.allocateEther(toDualAdd(vault1Inheritor2,vault1Inheritor1),toDualUINT(v1Inheritor2eAlloc-500,10000-500)); -v1VaultFacet.withdrawEther(freeEther+1000,vault1Owner); - -//no more free ether -freeEther=v1VaultFacet.getUnallocatedEther(); -assertEq(freeEther,0); -v1VaultFacet.allEtherAllocations(); + //unallocate from both inheritors + //ORDER matters(not really anymore) + v1dmsFacet.allocateEther( + toDualAdd(vault1Inheritor2, vault1Inheritor1), + toDualUINT(v1Inheritor2eAlloc - 500, 10000 - 500) + ); + v1EtherFacet.withdrawEther(freeEther + 1000, vault1Owner); + //no more free ether + freeEther = v1dmsFacet.getUnallocatedEther(); + assertEq(freeEther, 0); + v1dmsFacet.allEtherAllocations(); + } } - -} \ No newline at end of file From d73232ee55ae5ded84283f90bfd96479d1734811 Mon Sep 17 00:00:00 2001 From: mr-abims Date: Sun, 18 Dec 2022 19:34:22 +0100 Subject: [PATCH 4/4] added comment --- contracts/Vault/VaultDiamond.sol | 21 +- contracts/Vault/facets/DMSFacet.sol | 32 ++- contracts/Vault/facets/DiamondCutFacet.sol | 16 +- contracts/Vault/facets/DiamondLoupeFacet.sol | 42 +-- contracts/Vault/facets/ERC1155Facet.sol | 116 ++++---- contracts/Vault/facets/ERC20Facet.sol | 14 +- contracts/Vault/facets/ERC721Facet.sol | 116 +++----- contracts/Vault/facets/EtherFacet.sol | 13 +- contracts/Vault/facets/ModuleManagerFacet.sol | 5 +- contracts/Vault/facets/OwnershipFacet.sol | 2 +- contracts/Vault/libraries/LibArrayHelpers.sol | 52 +++- contracts/Vault/libraries/LibDMS.sol | 39 ++- contracts/Vault/libraries/LibDMSGuards.sol | 11 +- contracts/Vault/libraries/LibDiamond.sol | 94 +++++-- contracts/Vault/libraries/LibErrors.sol | 11 +- contracts/Vault/libraries/LibEther.sol | 19 +- contracts/Vault/libraries/LibGuards.sol | 1 + contracts/Vault/libraries/LibLayoutSilo.sol | 23 +- .../Vault/libraries/LibModuleManager.sol | 12 +- .../Vault/libraries/LibModuleUpgrades.sol | 4 +- .../Vault/libraries/LibStorageBinder.sol | 45 +-- contracts/Vault/libraries/LibTokens.sol | 263 ++++-------------- .../VaultFactory/VaultFactoryDiamond.sol | 23 +- .../facets/DiamondLoupeFactoryFacet.sol | 5 - .../facets/ModuleRegistryFacet.sol | 7 + .../VaultFactory/facets/VaultSpawnerFacet.sol | 25 +- .../libraries/LibFactoryAppStorage.sol | 3 +- .../libraries/LibFactoryDiamond.sol | 24 +- .../libraries/LibModuleRegistry.sol | 12 +- contracts/interfaces/IDiamondCut.sol | 22 +- contracts/interfaces/IDiamondLoupe.sol | 10 +- contracts/interfaces/IERC1155.sol | 29 +- contracts/interfaces/IERC721.sol | 57 ++-- contracts/interfaces/IModuleData.sol | 3 +- contracts/interfaces/IVaultDiamond.sol | 5 +- contracts/interfaces/IVaultFacet.sol | 5 +- contracts/interfaces/IVaultFactory.sol | 10 + test/DMSFacetTests.t.sol | 70 +---- test/DiamondDeployments.sol | 44 +-- test/ERC721FacetTest.t.sol | 75 ++--- test/EtherOpsTests.t.sol | 35 +-- test/MockERC1155.sol | 10 +- test/MockERC20.sol | 8 +- test/MockERC721.sol | 4 +- 44 files changed, 635 insertions(+), 802 deletions(-) diff --git a/contracts/Vault/VaultDiamond.sol b/contracts/Vault/VaultDiamond.sol index e7f3970..3cac10d 100644 --- a/contracts/Vault/VaultDiamond.sol +++ b/contracts/Vault/VaultDiamond.sol @@ -9,7 +9,7 @@ pragma solidity 0.8.4; import {LibDiamond} from "./libraries/LibDiamond.sol"; import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; -import {FacetAndSelectorData,DMSData} from "./libraries/LibLayoutSilo.sol"; +import {FacetAndSelectorData, DMSData} from "./libraries/LibLayoutSilo.sol"; import {LibStorageBinder} from "./libraries/LibStorageBinder.sol"; @@ -19,20 +19,25 @@ import "../interfaces/IVaultDiamond.sol"; contract VaultDiamond { address public vaultFactoryDiamond; - - constructor(IDiamondCut.FacetCut[] memory _selectorModule,IDiamondCut.FacetCut[] memory _tokenModule, address _vaultOwner) payable { + + /// @notice sets selector and token module at deployment + constructor( + IDiamondCut.FacetCut[] memory _selectorModule, + IDiamondCut.FacetCut[] memory _tokenModule, + address _vaultOwner + ) payable { LibDiamond.diamondCut(_selectorModule, address(0), ""); LibDiamond.diamondCut(_tokenModule, address(0), ""); //set module installation record to true - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); - fsData.activeModule["Selector"]=true; - fsData.activeModule["Token"]=true; + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); + fsData.activeModule["Selector"] = true; + fsData.activeModule["Token"] = true; fsData.activeModules.push("Selector"); fsData.activeModules.push("Token"); LibDiamond.setVaultOwner(_vaultOwner); - vaultFactoryDiamond=msg.sender; + vaultFactoryDiamond = msg.sender; } - + // Find facet for function that is called and execute the // function if a facet is found and return any value. diff --git a/contracts/Vault/facets/DMSFacet.sol b/contracts/Vault/facets/DMSFacet.sol index 83892fd..366cfa8 100644 --- a/contracts/Vault/facets/DMSFacet.sol +++ b/contracts/Vault/facets/DMSFacet.sol @@ -50,8 +50,7 @@ contract DMSFacet { uint256 amount; } - - + /// @notice checks throgh the vault and return dataa associated with it function inspectVault() public view returns (VaultInfo memory info) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); @@ -63,6 +62,7 @@ contract DMSFacet { info.inheritors = vaultData.inheritors; } + /// @notice returns all ethers that has been allocated from the vault function allEtherAllocations() public view returns (AllInheritorEtherAllocs[] memory eAllocs) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); uint256 count = vaultData.inheritors.length; @@ -73,6 +73,7 @@ contract DMSFacet { } } + /// @notice returns all ether allocates to _inheritor function inheritorEtherAllocation(address _inheritor) public view returns (uint256 _allocatedEther) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); if (!LibDMSGuards._anInheritor(_inheritor)) { @@ -81,10 +82,12 @@ contract DMSFacet { _allocatedEther = vaultData.inheritorWeishares[_inheritor]; } + // @notice retuns the amount of all ether that has been allocated in the vault function getAllocatedEther() public view returns (uint256) { return LibDMS.getCurrentAllocatedEth(); } + /// @notice returns the amoounf of free(unallocated) ether in the vault function getUnallocatedEther() public view returns (uint256 unallocated_) { uint256 currentBalance = address(this).balance; if (currentBalance > 0) { @@ -92,10 +95,12 @@ contract DMSFacet { } } + /// @notice returns the current ether balance of the vault function etherBalance() public view returns (uint256) { return address(this).balance; } + /// @notice gets the aloocated ERC20 tokens to inheritor function getAllocatedERC20Tokens(address _inheritor) public view returns (AllocatedERC20Tokens[] memory tAllocs) { LibDMSGuards._activeInheritor(_inheritor); DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); @@ -110,11 +115,13 @@ contract DMSFacet { } } + /// @notice returns the amount of a token aloocated to an inheritor function inheritorERC20TokenAllocation(address _inheritor, address _token) public view returns (uint256) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); return vaultData.inheritorTokenShares[_inheritor][_token]; } + /// @notice returns free(unallocated) ERC20 tokens in the vault function getUnallocatedTokens(address _token) public view returns (uint256 unallocated_) { uint256 bal = IERC20(_token).balanceOf(address(this)); uint256 allocated = LibDMS.getCurrentAllocatedTokens(_token); @@ -122,7 +129,7 @@ contract DMSFacet { unallocated_ = bal - allocated; } } - + /// @notice returns allocated ERC721 tokens to an inheritor function getAllocatedERC721Tokens(address _inheritor) public view @@ -141,18 +148,21 @@ contract DMSFacet { } } + /// @notice returns the amount of an ERC721 token allocated to an inheritor function getAllocatedERC721TokenIds(address _inheritor, address _token) external view returns (uint256[] memory) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); LibDMSGuards._activeInheritor(_inheritor); return vaultData.inheritorAllocatedTokenIds[_inheritor][_token]; } + /// @notice returns ERC721 token addresses allocated to an inheritor function getAllocatedERC721TokenAddresses(address _inheritor) public view returns (address[] memory) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); LibDMSGuards._activeInheritor(_inheritor); return vaultData.inheritorAllocatedERC721TokenAddresses[_inheritor]; } + /// @notice returns the amount of an ERC1155 token allocated to an inheritor function getAllocatedERC1155Tokens(address _token, address _inheritor) public view @@ -171,6 +181,7 @@ contract DMSFacet { } } + /// @notice returns all ERC1155 tokens allocated to an inheritor function getAllAllocatedERC1155Tokens(address _inheritor) public view @@ -192,6 +203,7 @@ contract DMSFacet { } } + /// @notice retuns free(unallocated) ERC1155 tokens in the vault function getUnallocatedERC115Tokens(address _token, uint256 _tokenId) public view returns (uint256 remaining_) { uint256 allocated = LibDMS.getCurrentAllocated1155tokens(_token, _tokenId); uint256 available = IERC1155(_token).balanceOf(address(this), _tokenId); @@ -204,26 +216,30 @@ contract DMSFacet { ///WRITE FUNCTIONS/// //////////////////// //note: owner restriction is in external fns + /// @notice adds inheritors and weishares to the vault function addInheritors(address[] calldata _newInheritors, uint256[] calldata _weiShare) external { LibGuards._onlyVaultOwner(); LibDMS._addInheritors(_newInheritors, _weiShare); } + /// @notice removes inheritors from the vault function removeInheritors(address[] calldata _inheritors) external { LibGuards._onlyVaultOwner(); LibDMS._removeInheritors(_inheritors); } - + /// @notice allocate ether to inheritors function allocateEther(address[] calldata _inheritors, uint256[] calldata _ethShares) external { LibGuards._onlyVaultOwner(); LibDMS._allocateEther(_inheritors, _ethShares); } + /// @notice allocate ERC20 tokens to inheritors function allocateERC20Tokens(address token, address[] calldata _inheritors, uint256[] calldata _shares) external { LibGuards._onlyVaultOwner(); LibDMS._allocateERC20Tokens(token, _inheritors, _shares); } + /// @notice allocate ERC721 tokens to inheritors function allocateERC721Tokens(address token, address[] calldata _inheritors, uint256[] calldata _tokenIDs) external { @@ -231,6 +247,7 @@ contract DMSFacet { LibDMS._allocateERC721Tokens(token, _inheritors, _tokenIDs); } + /// @notice allocate ERC1155 tokens to inheritors function allocateERC1155Tokens( address token, address[] calldata _inheritors, @@ -241,26 +258,29 @@ contract DMSFacet { LibDMS._allocateERC1155Tokens(token, _inheritors, _tokenIDs, _amounts); } + /// @notice transfer vault ownership to _newVaultOwner function transferOwnership(address _newVaultOwner) public { LibGuards._onlyVaultOwner(); LibDMS._transferOwnerShip(_newVaultOwner); } - + /// @notice transfer vault backup to _newBackupAddress function transferBackup(address _newBackupAddress) public { LibDMSGuards._onlyVaultOwnerOrBackup(); LibDMS._transferBackup(_newBackupAddress); } //CLAIMS + /// @notice allow backup address to claim ownership function claimOwnership(address _newBackupAddress) public { LibDMSGuards._enforceIsBackupAddress(); LibDMS._claimOwnership(_newBackupAddress); } + /// @notice allow inheritor to claim all allocated assets function claimAllAllocations() external { LibDMS._claimAll(); } - + /// @notice pings vault and resets inactivity timer function ping() external { LibGuards._onlyVaultOwner(); LibDMS._ping(); diff --git a/contracts/Vault/facets/DiamondCutFacet.sol b/contracts/Vault/facets/DiamondCutFacet.sol index f1c4a80..1ea0719 100644 --- a/contracts/Vault/facets/DiamondCutFacet.sol +++ b/contracts/Vault/facets/DiamondCutFacet.sol @@ -1,10 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.4; -/******************************************************************************\ -* Author: Nick Mudge (https://twitter.com/mudgen) -* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 -/******************************************************************************/ +/** + * \ + * Author: Nick Mudge (https://twitter.com/mudgen) + * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 + * /***************************************************************************** + */ import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; @@ -22,11 +24,7 @@ contract DiamondCutFacet is IDiamondCut { /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init - function diamondCut( - FacetCut[] calldata _diamondCut, - address _init, - bytes calldata _calldata - ) external override { + function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external override { // restrict upgrades to VaultFactoryDiamond only // if (msg.sender !=IVaultDiamond(address(this)).vaultFactoryDiamond()) revert LibErrors.NoPermissions(); LibDiamond.diamondCut(_diamondCut, _init, _calldata); diff --git a/contracts/Vault/facets/DiamondLoupeFacet.sol b/contracts/Vault/facets/DiamondLoupeFacet.sol index 119d765..3f8cf09 100644 --- a/contracts/Vault/facets/DiamondLoupeFacet.sol +++ b/contracts/Vault/facets/DiamondLoupeFacet.sol @@ -1,30 +1,29 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.4; -/******************************************************************************\ -* Author: Nick Mudge (https://twitter.com/mudgen) -* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 -/******************************************************************************/ +/** + * \ + * Author: Nick Mudge (https://twitter.com/mudgen) + * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 + * /***************************************************************************** + */ //import "../libraries/LibVaultStorage.sol"; import "../libraries/LibDiamond.sol"; -import { IDiamondLoupe } from "../../interfaces/IDiamondLoupe.sol"; -import { IERC165 } from "../../interfaces/IERC165.sol"; +import {IDiamondLoupe} from "../../interfaces/IDiamondLoupe.sol"; +import {IERC165} from "../../interfaces/IERC165.sol"; import "../libraries/LibLayoutSilo.sol"; import "../libraries/LibStorageBinder.sol"; - contract DiamondLoupeFacet is IDiamondLoupe, IERC165 { - // Diamond Loupe Functions //////////////////////////////////////////////////////////////////// /// These functions are expected to be called frequently by tools. - /// @notice Gets all facets and their selectors. /// @return facets_ Facet - function facets() external override view returns (Facet[] memory facets_) { - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + function facets() external view override returns (Facet[] memory facets_) { + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); uint256 numFacets = fsData.facetAddresses.length; facets_ = new Facet[](numFacets); for (uint256 i; i < numFacets; i++) { @@ -37,15 +36,20 @@ contract DiamondLoupeFacet is IDiamondLoupe, IERC165 { /// @notice Gets all the function selectors provided by a facet. /// @param _facet The facet address. /// @return facetFunctionSelectors_ - function facetFunctionSelectors(address _facet) external override view returns (bytes4[] memory facetFunctionSelectors_) { - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + function facetFunctionSelectors(address _facet) + external + view + override + returns (bytes4[] memory facetFunctionSelectors_) + { + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); facetFunctionSelectors_ = fsData.facetFunctionSelectors[_facet].functionSelectors; } /// @notice Get all the facet addresses used by a diamond. /// @return facetAddresses_ - function facetAddresses() external override view returns (address[] memory facetAddresses_) { - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + function facetAddresses() external view override returns (address[] memory facetAddresses_) { + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); facetAddresses_ = fsData.facetAddresses; } @@ -53,14 +57,14 @@ contract DiamondLoupeFacet is IDiamondLoupe, IERC165 { /// @dev If facet is not found return address(0). /// @param _functionSelector The function selector. /// @return facetAddress_ The facet address. - function facetAddress(bytes4 _functionSelector) external override view returns (address facetAddress_) { - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + function facetAddress(bytes4 _functionSelector) external view override returns (address facetAddress_) { + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); facetAddress_ = fsData.selectorToFacetAndPosition[_functionSelector].facetAddress; } // This implements ERC-165. - function supportsInterface(bytes4 _interfaceId) external override view returns (bool) { - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + function supportsInterface(bytes4 _interfaceId) external view override returns (bool) { + FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); return fsData.supportedInterfaces[_interfaceId]; } } diff --git a/contracts/Vault/facets/ERC1155Facet.sol b/contracts/Vault/facets/ERC1155Facet.sol index 99d111a..4caf2c9 100644 --- a/contracts/Vault/facets/ERC1155Facet.sol +++ b/contracts/Vault/facets/ERC1155Facet.sol @@ -2,88 +2,68 @@ pragma solidity 0.8.4; import "../libraries/LibDMS.sol"; -import {LibTokens,ERC1155_ACCEPTED,ERC1155_BATCH_ACCEPTED} from "../libraries/LibTokens.sol"; +import {LibTokens, ERC1155_ACCEPTED, ERC1155_BATCH_ACCEPTED} from "../libraries/LibTokens.sol"; import "../libraries/LibLayoutSilo.sol"; import "../libraries/LibStorageBinder.sol"; import "../libraries/LibGuards.sol"; contract ERC1155Facet { - //DEPOSITS - function depositERC1155Token( - address _token, - uint256 _tokenID, - uint256 _amount - ) external { - // LibGuards._onlyVaultOwner(); - LibTokens._safeInputERC1155Token(_token, _tokenID, _amount); - } - - function batchDepositERC1155Tokens( - address _token, - uint256[] calldata _tokenIDs, - uint256[] calldata _amounts - ) external { - // LibGuards._onlyVaultOwner(); - LibTokens._safeBatchInputERC1155Tokens(_token, _tokenIDs, _amounts); - } - - //WITHDRAWALS - - function withdrawERC1155Token( - address _token, - uint256 _tokenID, - uint256 _amount, - address _to - ) public { - LibGuards._onlyVaultOwner(); - LibTokens._withdrawERC1155Token(_token, _tokenID, _amount, _to); - } + //DEPOSITS + /// @notice deposits ERC1155 token into the vault + function depositERC1155Token(address _token, uint256 _tokenID, uint256 _amount) external { + // LibGuards._onlyVaultOwner(); + LibTokens._safeInputERC1155Token(_token, _tokenID, _amount); + } + /// @notice allows caller to deposit an ERC1155 with multiple tokenIDs into the vault + function batchDepositERC1155Tokens(address _token, uint256[] calldata _tokenIDs, uint256[] calldata _amounts) + external + { + // LibGuards._onlyVaultOwner(); + LibTokens._safeBatchInputERC1155Tokens(_token, _tokenIDs, _amounts); + } - function batchWithdrawERC1155Token( - address _token, - uint256[] calldata _tokenIDs, - uint256[] calldata _amount, - address _to - ) public { - LibGuards._onlyVaultOwner(); - if (_tokenIDs.length > 0) { - for (uint256 i; i < _tokenIDs.length; i++) { - withdrawERC1155Token(_token, _tokenIDs[i], _amount[i], _to); - } + //WITHDRAWALS + /// @notice withdraws an ERC1155 token from the vault + function withdrawERC1155Token(address _token, uint256 _tokenID, uint256 _amount, address _to) public { + LibGuards._onlyVaultOwner(); + LibTokens._withdrawERC1155Token(_token, _tokenID, _amount, _to); } - } - //APPROVALS - function approveERC1155Token( - address _token, - address _to, - bool _approved - ) external { - LibGuards._onlyVaultOwner(); - LibTokens._approveAllERC1155Token(_token, _to, _approved); - } + /// @notice allows caller to withdraw a unit of ERC155 token with multiple tokenIDs from the vault + function batchWithdrawERC1155Token( + address _token, + uint256[] calldata _tokenIDs, + uint256[] calldata _amount, + address _to + ) public { + LibGuards._onlyVaultOwner(); + if (_tokenIDs.length > 0) { + for (uint256 i; i < _tokenIDs.length; i++) { + withdrawERC1155Token(_token, _tokenIDs[i], _amount[i], _to); + } + } + } - //DEPOSIT COMPATIBILITY + //APPROVALS + /// @notice approves an ERC1155 token to be spent by _to + function approveERC1155Token(address _token, address _to, bool _approved) external { + LibGuards._onlyVaultOwner(); + LibTokens._approveAllERC1155Token(_token, _to, _approved); + } -function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public pure returns (bytes4) { + //DEPOSIT COMPATIBILITY + /// @notice checks if ERC155 token deposit is allowed in the vault + function onERC1155Received(address, address, uint256, uint256, bytes memory) public pure returns (bytes4) { return ERC1155_ACCEPTED; } - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public pure returns (bytes4) { + /// @notice checks if ERC155 token batch deposit is allowed in the vault + function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) + public + pure + returns (bytes4) + { return ERC1155_BATCH_ACCEPTED; } - } diff --git a/contracts/Vault/facets/ERC20Facet.sol b/contracts/Vault/facets/ERC20Facet.sol index 58ab3fb..22a6244 100644 --- a/contracts/Vault/facets/ERC20Facet.sol +++ b/contracts/Vault/facets/ERC20Facet.sol @@ -1,42 +1,40 @@ pragma solidity 0.8.4; - import {LibTokens} from "../libraries/LibTokens.sol"; import "../libraries/LibLayoutSilo.sol"; import "../libraries/LibStorageBinder.sol"; - import {LibGuards} from "../libraries/LibGuards.sol"; -contract ERC20Facet { - - - +contract ERC20Facet { //DEPOSITS + /// @notice deposits ERC20 token into the vault function depositERC20Token(address _token, uint256 _amount) external { // LibGuards._onlyVaultOwner(); LibTokens._inputERC20Token(_token, _amount); } + /// @notice deposits multiple ERC20 tokens into the vault function depositERC20Tokens(address[] calldata _tokens, uint256[] calldata _amounts) external { //LibGuards._onlyVaultOwner(); LibTokens._inputERC20Tokens(_tokens, _amounts); } //WITHDRAWALS - + /// @notice withdraws an ERC20 token from the vault function withdrawERC20Token(address _token, uint256 _amount, address _to) public { LibGuards._onlyVaultOwner(); LibTokens._withdrawERC20Token(_token, _amount, _to); } - + /// @notice allows caller to withdraw multiple ERC20 tokens from the vault function batchWithdrawERC20Token(address[] calldata _tokens, uint256[] calldata _amounts, address _to) public { LibGuards._onlyVaultOwner(); LibTokens._withdrawERC20Tokens(_tokens, _amounts, _to); } //APPROVALS + /// @notice approves an ERC20 token to be spent by _to function approveERC20Token(address _token, address _to, uint256 _amount) external { LibGuards._onlyVaultOwner(); LibTokens._approveERC20Token(_token, _to, _amount); diff --git a/contracts/Vault/facets/ERC721Facet.sol b/contracts/Vault/facets/ERC721Facet.sol index 3aaa42d..4a190dd 100644 --- a/contracts/Vault/facets/ERC721Facet.sol +++ b/contracts/Vault/facets/ERC721Facet.sol @@ -9,82 +9,56 @@ import "../libraries/LibStorageBinder.sol"; import {LibDMSGuards} from "../libraries/LibDMSGuards.sol"; import {LibGuards} from "../libraries/LibGuards.sol"; -import {ERC1155_BATCH_ACCEPTED,ERC1155_ACCEPTED,ERC721WithCall} from "../libraries/LibTokens.sol"; - -contract ERC721Facet { - - - //DEPOSITS - - function depositERC721Token( - address _token, - uint256 _tokenID - ) external { - // LibDMSGuards._onlyVaultOwner(); - LibTokens._inputERC721Token(_token, _tokenID); - } - - function depositERC721Tokens(address _token,uint256[] calldata _tokenIDs) external{ - for(uint256 i;i<_tokenIDs.length;i++){ - LibTokens._inputERC721Token(_token,_tokenIDs[i]); +import {ERC1155_BATCH_ACCEPTED, ERC1155_ACCEPTED, ERC721WithCall} from "../libraries/LibTokens.sol"; + +contract ERC721Facet { + //DEPOSITS + /// @notice deposits ERC721 token into the vault + function depositERC721Token(address _token, uint256 _tokenID) external { + // LibDMSGuards._onlyVaultOwner(); + LibTokens._inputERC721Token(_token, _tokenID); + } + /// @notice allows caller to deposit an ERC721 token with multiple Ids into the vault + function depositERC721Tokens(address _token, uint256[] calldata _tokenIDs) external { + for (uint256 i; i < _tokenIDs.length; i++) { + LibTokens._inputERC721Token(_token, _tokenIDs[i]); + } } - } - - function safeDepositERC721Token( - address _token, - uint256 _tokenID - ) external { - // LibDMSGuards._onlyVaultOwner(); - LibTokens._safeInputERC721Token(_token, _tokenID); - } - - - - function safeDepositERC721TokenAndCall( - address _token, - uint256 _tokenID,bytes calldata data - ) external { - //LibDMSGuards._onlyVaultOwner(); - LibTokens._safeInputERC721TokenAndCall(_token, _tokenID,data); - } - - - //WITHDRAWALS - function withdrawERC721Token( - address _token, - uint256 _tokenID, - address _to - ) public { - LibGuards._onlyVaultOwner(); - LibTokens._withdrawERC721Token(_token, _tokenID, _to); - } + /// @notice allows user to deposit an ERC721 token via the safeTransferFrom method + function safeDepositERC721Token(address _token, uint256 _tokenID) external { + // LibDMSGuards._onlyVaultOwner(); + LibTokens._safeInputERC721Token(_token, _tokenID); + } -//APPROVALS - function approveSingleERC721Token( - address _token, - address _to, - uint256 _tokenID - ) external { - LibGuards._onlyVaultOwner(); - LibTokens._approveERC721Token(_token, _tokenID,_to); - } + /// @notice allow safe deposit of ERC721 token with data + function safeDepositERC721TokenAndCall(address _token, uint256 _tokenID, bytes calldata data) external { + //LibDMSGuards._onlyVaultOwner(); + LibTokens._safeInputERC721TokenAndCall(_token, _tokenID, data); + } -function approveAllERC721Token(address _token,address _to,bool _approved) external { - LibGuards._onlyVaultOwner(); - LibTokens._approveAllERC721Token(_token,_to,_approved); -} + //WITHDRAWALS + /// @notice withdraws an ERC721 token from the vault + function withdrawERC721Token(address _token, uint256 _tokenID, address _to) public { + LibGuards._onlyVaultOwner(); + LibTokens._withdrawERC721Token(_token, _tokenID, _to); + } -//DEPOSIT COMPATIBILITY + //APPROVALS + /// @notice approves a unit of ERC721 token to be spent by _to + function approveSingleERC721Token(address _token, address _to, uint256 _tokenID) external { + LibGuards._onlyVaultOwner(); + LibTokens._approveERC721Token(_token, _tokenID, _to); + } + /// @notice approves all ERC721 tokens to be spent by _to + function approveAllERC721Token(address _token, address _to, bool _approved) external { + LibGuards._onlyVaultOwner(); + LibTokens._approveAllERC721Token(_token, _to, _approved); + } - function onERC721Received( - address, - address, - uint256, - bytes memory - ) public pure returns (bytes4) { + //DEPOSIT COMPATIBILITY + /// @notice checks if onERC721Received is implemented + function onERC721Received(address, address, uint256, bytes memory) public pure returns (bytes4) { return ERC721WithCall; } - - -} \ No newline at end of file +} diff --git a/contracts/Vault/facets/EtherFacet.sol b/contracts/Vault/facets/EtherFacet.sol index 78ee55c..2aea4e3 100644 --- a/contracts/Vault/facets/EtherFacet.sol +++ b/contracts/Vault/facets/EtherFacet.sol @@ -1,18 +1,19 @@ - pragma solidity 0.8.4; import {LibErrors} from "../libraries/LibErrors.sol"; import {LibDiamond} from "../libraries/LibDiamond.sol"; import {LibGuards} from "../libraries/LibGuards.sol"; import {LibEther} from "../libraries/LibEther.sol"; -contract EtherFacet { - function depositEther(uint256 _amount) external payable { - LibEther._depositEther(_amount); +contract EtherFacet { + //DEPOSITS + /// @notice deposits Ether into the vault + function depositEther(uint256 _amount) external payable { + LibEther._depositEther(_amount); } - + /// @notice allows caller to withdraw Ether from the vault function withdrawEther(uint256 _amount, address _to) external { LibGuards._onlyVaultOwner(); LibEther._withdrawEth(_amount, _to); } -} \ No newline at end of file +} diff --git a/contracts/Vault/facets/ModuleManagerFacet.sol b/contracts/Vault/facets/ModuleManagerFacet.sol index 5364260..7671af3 100644 --- a/contracts/Vault/facets/ModuleManagerFacet.sol +++ b/contracts/Vault/facets/ModuleManagerFacet.sol @@ -5,23 +5,26 @@ import "../libraries/LibLayoutSilo.sol"; import "../libraries/LibModuleUpgrades.sol"; contract ModuleManagerFacet { + /// @notice returns the active modules in the vault function getActiveModules() external view returns (string[] memory) { FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); return fsData.activeModules; } + /// @notice checks if a module is active in vault function isActiveModule(string memory _name) external view returns (bool exists_) { FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); exists_ = fsData.activeModule[_name]; } //upgrade - + /// @notice allows vaul to be upgraded with a module function upgradeVaultWithModule(string calldata _name) external { LibModuleUpgrades._upgradeVaultWithModule(_name); } //downgrade + /// @notice allows vault to be downgraded by removing a module function downgradeVaultWithModule(string calldata _name) external { LibModuleUpgrades._downgradeVaultWithModule(_name); } diff --git a/contracts/Vault/facets/OwnershipFacet.sol b/contracts/Vault/facets/OwnershipFacet.sol index 537a9c0..7c3b2d3 100644 --- a/contracts/Vault/facets/OwnershipFacet.sol +++ b/contracts/Vault/facets/OwnershipFacet.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.4; import {LibDiamond} from "../libraries/LibDiamond.sol"; - contract OwnershipFacet { + /// @notice returns the owner of the vault function owner() external view returns (address owner_) { owner_ = LibDiamond.vaultOwner(); } diff --git a/contracts/Vault/libraries/LibArrayHelpers.sol b/contracts/Vault/libraries/LibArrayHelpers.sol index 227474d..b124042 100644 --- a/contracts/Vault/libraries/LibArrayHelpers.sol +++ b/contracts/Vault/libraries/LibArrayHelpers.sol @@ -1,7 +1,13 @@ pragma solidity 0.8.4; library LibArrayHelpers { - function findAddIndex(address _item, address[] memory addressArray) internal pure returns (uint256 i) { + /// @notice check an address index in an array + /// @param _item address to be checked + /// @param addressArray arrays to be checked + function findAddIndex( + address _item, + address[] memory addressArray + ) internal pure returns (uint256 i) { for (i; i < addressArray.length; i++) { //using the conventional method since we cannot have duplicate addresses if (addressArray[i] == _item) { @@ -10,7 +16,14 @@ library LibArrayHelpers { } } - function findUintIndex(uint256 _item, uint256[] memory noArray) internal pure returns (uint256 i) { + /// @dev checks item index in an array + /// @param _item to be checked + /// @param noArray array to be looped through + + function findUintIndex( + uint256 _item, + uint256[] memory noArray + ) internal pure returns (uint256 i) { for (i; i < noArray.length; i++) { if (noArray[i] == _item) { return i; @@ -18,7 +31,11 @@ library LibArrayHelpers { } } - function findStringIndex(string memory _item, string[] memory stringArray) internal pure returns (uint256 i) { + /// @notice check for sring index given an array + function findStringIndex( + string memory _item, + string[] memory stringArray + ) internal pure returns (uint256 i) { for (i; i < stringArray.length; i++) { if (__equalTo__(stringArray[i], _item)) { return i; @@ -26,11 +43,20 @@ library LibArrayHelpers { } } - function __equalTo__(string memory a, string memory b) private pure returns (bool) { - return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b)))); + /// @dev checks for eqaulity of two strings + function __equalTo__( + string memory a, + string memory b + ) private pure returns (bool) { + return (keccak256(abi.encodePacked((a))) == + keccak256(abi.encodePacked((b)))); } - function removeString(string[] storage _stringArray, string memory to) internal { + /// @dev removes string from an array + function removeString( + string[] storage _stringArray, + string memory to + ) internal { require(_stringArray.length > 0, "Non-elemented number array"); uint256 index = findStringIndex(to, _stringArray); if (_stringArray.length == 1) { @@ -44,6 +70,7 @@ library LibArrayHelpers { } } + /// @dev removes uint from an array function removeUint(uint256[] storage _noArray, uint256 to) internal { require(_noArray.length > 0, "Non-elemented number array"); uint256 index = findUintIndex(to, _noArray); @@ -58,6 +85,7 @@ library LibArrayHelpers { } } + /// @notice removes address form _array[] function removeAddress(address[] storage _array, address _add) internal { require(_array.length > 0, "Non-elemented address array"); uint256 index = findAddIndex(_add, _array); @@ -73,7 +101,11 @@ library LibArrayHelpers { } } - function _inUintArray(uint256[] memory _array, uint256 _targ) internal pure returns (bool exists_) { + /// @notice checks fif an integer is included in the selected array + function _inUintArray( + uint256[] memory _array, + uint256 _targ + ) internal pure returns (bool exists_) { if (_array.length > 0) { for (uint256 i; i < _array.length; i++) { if (_targ == _array[i]) { @@ -83,7 +115,11 @@ library LibArrayHelpers { } } - function _inAddressArray(address[] memory _array, address _targ) internal pure returns (bool exists_) { + /// @dev checks for _targ address in _array + function _inAddressArray( + address[] memory _array, + address _targ + ) internal pure returns (bool exists_) { if (_array.length > 0) { for (uint256 i; i < _array.length; i++) { if (_targ == _array[i]) { diff --git a/contracts/Vault/libraries/LibDMS.sol b/contracts/Vault/libraries/LibDMS.sol index ab406f1..54137b0 100644 --- a/contracts/Vault/libraries/LibDMS.sol +++ b/contracts/Vault/libraries/LibDMS.sol @@ -43,14 +43,14 @@ library LibDMS { error InactiveInheritor(); error NoAllocatedTokens(); - //owner check is in external fn + /// @notice pings vault and resets the timeline for inactivity function _ping() internal { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); vaultData.lastPing = block.timestamp; emit VaultPinged(block.timestamp, LibDiamond.vaultID()); } - - function getCurrentAllocatedEth() internal view returns (uint256) { + /// @notice gets the total ETH allocated in a vault + function getCurrentAllocatedEth() internal view returns (uint256) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); uint256 totalEthAllocated; for (uint256 x; x < vaultData.inheritors.length; x++) { @@ -59,6 +59,7 @@ library LibDMS { return totalEthAllocated; } + /// @dev returns the total amount of an allocated token function getCurrentAllocatedTokens(address _token) internal view returns (uint256) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); uint256 totalTokensAllocated; @@ -68,6 +69,7 @@ library LibDMS { return totalTokensAllocated; } + /// @notice returns the allocated amount of an Erc1155 id function getCurrentAllocated1155tokens(address _token, uint256 _tokenID) internal view returns (uint256 alloc_) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); for (uint256 x; x < vaultData.inheritors.length; x++) { @@ -75,11 +77,14 @@ library LibDMS { } } + /// @notice checks if an ERC 721 token has been allocated function _isERC721Allocated(address _token, uint256 _tokenId) internal view returns (bool allocated_) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); allocated_ = vaultData.allocatedERC721Tokens[_token][_tokenId]; } + /// @notice this removes all the tokens that have + /// been previously allocated to an inheritor for all token types function _resetClaimed(address _inheritor) internal { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); vaultData.inheritorWeishares[_inheritor] = 0; @@ -98,7 +103,8 @@ library LibDMS { } } - //only used for multiple address elemented arrays + /// @notice resets allocated tokens + /// only used for multiple address elemented arrays function reset(address _inheritor) internal { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); vaultData.inheritorWeishares[_inheritor] = 0; @@ -106,7 +112,8 @@ library LibDMS { if (vaultData.inheritorAllocatedERC20Tokens[_inheritor].length > 0) { for (uint256 x; x < vaultData.inheritorAllocatedERC20Tokens[_inheritor].length; x++) { vaultData.inheritorTokenShares[_inheritor][vaultData.inheritorAllocatedERC20Tokens[_inheritor][x]] = 0; - vaultData.inheritorActiveTokens[_inheritor][vaultData.inheritorAllocatedERC20Tokens[_inheritor][x]] = false; + vaultData.inheritorActiveTokens[_inheritor][vaultData.inheritorAllocatedERC20Tokens[_inheritor][x]] = + false; } //remove all token addresses delete vaultData.inheritorAllocatedERC20Tokens[_inheritor]; @@ -141,7 +148,7 @@ library LibDMS { } //INHERITOR MUTATING OPERATIONS - + /// @dev adds new set of inheritors to a vault with their wei shares function _addInheritors(address[] calldata _newInheritors, uint256[] calldata _weiShare) internal { if (_newInheritors.length == 0 || _weiShare.length == 0) { revert LibErrors.EmptyArray(); @@ -172,6 +179,7 @@ library LibDMS { emit EthAllocated(_newInheritors, _weiShare, LibDiamond.vaultID()); } + /// @notice removes inheritors from vaulr function _removeInheritors(address[] calldata _inheritors) internal { if (_inheritors.length == 0) { revert LibErrors.EmptyArray(); @@ -194,6 +202,7 @@ library LibDMS { //ALLOCATION MUTATING OPERATIONS + /// @notice allocate ether to active inheritors of a vault function _allocateEther(address[] calldata _inheritors, uint256[] calldata _ethShares) internal { if (_inheritors.length == 0 || _ethShares.length == 0) { revert LibErrors.EmptyArray(); @@ -218,6 +227,7 @@ library LibDMS { emit EthAllocated(_inheritors, _ethShares, LibDiamond.vaultID()); } + /// @notice allocate token to aactive inheritors with their respective shares function _allocateERC20Tokens(address token, address[] calldata _inheritors, uint256[] calldata _shares) internal { if (_inheritors.length == 0 || _shares.length == 0) { revert LibErrors.EmptyArray(); @@ -255,6 +265,7 @@ library LibDMS { emit ERC20TokensAllocated(token, _inheritors, _shares, LibDiamond.vaultID()); } + /// @notice allocates ERC721 tokens to active inheritors function _allocateERC721Tokens(address _token, address[] calldata _inheritors, uint256[] calldata _tokenIDs) internal { @@ -337,14 +348,16 @@ library LibDMS { _ping(); } + /// @notice allocates ERC115 tokens to active inheritors + /// @param _inheritors to be added + /// @param _tokenIDs of ERC155 to be allocated + /// @param _amounts of the token to be allocated to inheritor function _allocateERC1155Tokens( address _token, address[] calldata _inheritors, uint256[] calldata _tokenIDs, uint256[] calldata _amounts - ) - internal - { + ) internal { if (_inheritors.length == 0 || _tokenIDs.length == 0) { revert LibErrors.EmptyArray(); } @@ -399,7 +412,7 @@ library LibDMS { } //ACCESS TRANSFER - + //// @notice transfers vault ownership to new owner function _transferOwnerShip(address _newOwner) internal { FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); address prevOwner = fsData.vaultOwner; @@ -407,6 +420,7 @@ library LibDMS { emit OwnershipTransferred(prevOwner, _newOwner, LibDiamond.vaultID()); } + /// @notice sets a new backup address function _transferBackup(address _newBackupAddress) internal { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); address prevBackup = vaultData.backupAddress; @@ -416,6 +430,7 @@ library LibDMS { ///CLAIMS + /// @notice transfers vault ownership to caller and sets new backup address function _claimOwnership(address _newBackup) internal { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); @@ -429,6 +444,7 @@ library LibDMS { emit BackupTransferred(prevBackup, _newBackup, LibDiamond.vaultID()); } + /// @notice allows an inheritor to claim their ERC20 tokens share from the vault function _claimERC20Tokens() internal { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); uint256 tokens = vaultData.inheritorAllocatedERC20Tokens[msg.sender].length; @@ -449,6 +465,7 @@ library LibDMS { } } + /// @notice allows inheritor to claim the ERC721 token allocated to them from the vault function _claimERC721Tokens() internal { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); uint256 tokens = vaultData.inheritorAllocatedERC721TokenAddresses[msg.sender].length; @@ -481,6 +498,7 @@ library LibDMS { } } + /// @notice allows inheritors to claim the ERC1155 tokens allocated to them from the vault function _claimERC1155Tokens() internal { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); uint256 tokens = vaultData.inheritorAllocatedERC1155TokenAddresses[msg.sender].length; @@ -506,6 +524,7 @@ library LibDMS { } } + /// @notice allows an inheritor to claim all tokens allocated to them in a single transaction function _claimAll() internal { LibDMSGuards._anInheritor(msg.sender); LibDMSGuards._activeInheritor(msg.sender); diff --git a/contracts/Vault/libraries/LibDMSGuards.sol b/contracts/Vault/libraries/LibDMSGuards.sol index e3f1e9e..bfe1d79 100644 --- a/contracts/Vault/libraries/LibDMSGuards.sol +++ b/contracts/Vault/libraries/LibDMSGuards.sol @@ -11,7 +11,7 @@ error HasExpired(); error Claimed(); library LibDMSGuards { - //check + /// @notice ensures that a caller is vault owner or backup address function _onlyVaultOwnerOrBackup() internal view { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); FacetAndSelectorData storage fsData = LibStorageBinder._bindAndReturnFacetStorage(); @@ -19,6 +19,7 @@ library LibDMSGuards { revert NotOwnerOrBackupAddress(); } } + /// @dev checks that caller is a backup address function _enforceIsBackupAddress() internal view { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); @@ -26,6 +27,7 @@ library LibDMSGuards { revert NotBackupAddress(); } } + /// checks if an address is an active inheritor on a vault function _activeInheritor(address _inheritor) internal view returns (bool active_) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); @@ -35,6 +37,7 @@ library LibDMSGuards { active_ = (vaultData.activeInheritors[_inheritor]); } } + /// checks if an address has been set as inheritor function _anInheritor(address _inheritor) internal view returns (bool inh) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); @@ -48,7 +51,7 @@ library LibDMSGuards { } } } - + /// checks if address is an inheritor or address(0) function _anInheritorOrZero(address _inheritor) internal view returns (bool inh) { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); if (_inheritor == address(0)) { @@ -62,6 +65,7 @@ library LibDMSGuards { } } + /// checks if the vault timeline for inactivity has expired function _expired() internal view { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); if (block.timestamp - vaultData.lastPing <= 24 weeks) { @@ -69,13 +73,14 @@ library LibDMSGuards { } } + /// checks if the vault timeline for inactivity is still valid function _notExpired() internal view { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); if (block.timestamp - vaultData.lastPing > 24 weeks) { revert HasExpired(); } } - + /// @notice check if an inheritor has claimed the assets allocated to them function _notClaimed(address _inheritor) internal view { DMSData storage vaultData = LibStorageBinder._bindAndReturnDMSStorage(); if (vaultData.claimed[_inheritor]) { diff --git a/contracts/Vault/libraries/LibDiamond.sol b/contracts/Vault/libraries/LibDiamond.sol index 64466bf..9004ff9 100644 --- a/contracts/Vault/libraries/LibDiamond.sol +++ b/contracts/Vault/libraries/LibDiamond.sol @@ -31,37 +31,51 @@ library LibDiamond { address indexed newOwner ); + /// @dev sets vault owner address + /// @param _newOwner address function setVaultOwner(address _newOwner) internal { - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + FacetAndSelectorData storage fsData = LibStorageBinder + ._bindAndReturnFacetStorage(); address previousOwner = fsData.vaultOwner; fsData.vaultOwner = _newOwner; emit OwnershipTransferred(previousOwner, _newOwner); } - - + /// @notice returns the address current vault owner function vaultOwner() internal view returns (address contractOwner_) { - contractOwner_ = LibStorageBinder._bindAndReturnFacetStorage().vaultOwner; + contractOwner_ = LibStorageBinder + ._bindAndReturnFacetStorage() + .vaultOwner; } - function vaultID() internal view returns(uint256 vaultID_){ - vaultID_=LibStorageBinder._bindAndReturnFacetStorage().vaultID; + /// @dev returns the ID assigned to a vault + function vaultID() internal view returns (uint256 vaultID_) { + vaultID_ = LibStorageBinder._bindAndReturnFacetStorage().vaultID; } - function enforceIsContractOwner() internal view{ - if (msg.sender != LibStorageBinder._bindAndReturnFacetStorage().vaultOwner) revert NotVaultOwner(); + /// @notice ensures that caller is the owner + function enforceIsContractOwner() internal view { + if ( + msg.sender != + LibStorageBinder._bindAndReturnFacetStorage().vaultOwner + ) revert NotVaultOwner(); + } + + /// @notice returns Vault Factory Diamond address + function vaultFactory() internal view returns (address) { + return IVaultDiamond(address(this)).vaultFactoryDiamond(); } -function vaultFactory() internal view returns(address){ - return IVaultDiamond(address(this)).vaultFactoryDiamond(); -} event DiamondCut( IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata ); - // Internal function version of diamondCut + /// @notice Add/replace/remove any number of functions + /// @param _diamondCut Contains the facet addresses and function selectors + /// @param _init The address of the contract or facet to execute _calldata + /// @param _calldata A function call, including function selector and arguments function diamondCut( IDiamondCut.FacetCut[] memory _diamondCut, address _init, @@ -96,15 +110,22 @@ function vaultFactory() internal view returns(address){ initializeDiamondCut(_init, _calldata); } + /// @notice adds new functions to a facet + /// @param _facetAddress facet where the function will be added + /// @param _functionSelectors arrays of functions to be added function addFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { if (_functionSelectors.length <= 0) revert NoSelectorsInFacet(); - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + FacetAndSelectorData storage fsData = LibStorageBinder + ._bindAndReturnFacetStorage(); if (_facetAddress == address(0)) revert NoZeroAddress(); uint96 selectorPosition = uint96( - fsData.facetFunctionSelectors[_facetAddress].functionSelectors.length + fsData + .facetFunctionSelectors[_facetAddress] + .functionSelectors + .length ); // add new facet address if it does not exist if (selectorPosition == 0) { @@ -125,15 +146,20 @@ function vaultFactory() internal view returns(address){ } } + /// @notice replaces functions in a selected facet function replaceFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { if (_functionSelectors.length <= 0) revert NoSelectorsInFacet(); - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + FacetAndSelectorData storage fsData = LibStorageBinder + ._bindAndReturnFacetStorage(); if (_facetAddress == address(0)) revert NoZeroAddress(); uint96 selectorPosition = uint96( - fsData.facetFunctionSelectors[_facetAddress].functionSelectors.length + fsData + .facetFunctionSelectors[_facetAddress] + .functionSelectors + .length ); // add new facet address if it does not exist if (selectorPosition == 0) { @@ -156,12 +182,14 @@ function vaultFactory() internal view returns(address){ } } + /// @notice removes functions in a facet function removeFunctions( address _facetAddress, bytes4[] memory _functionSelectors ) internal { if (_functionSelectors.length <= 0) revert NoSelectorsInFacet(); - FacetAndSelectorData storage fsData=LibStorageBinder._bindAndReturnFacetStorage(); + FacetAndSelectorData storage fsData = LibStorageBinder + ._bindAndReturnFacetStorage(); // if function does not exist then do nothing and return if (_facetAddress != address(0)) revert MustBeZeroAddress(); for ( @@ -177,14 +205,24 @@ function vaultFactory() internal view returns(address){ } } - function addFacet(FacetAndSelectorData storage fsData, address _facetAddress) internal { + /// @notice add facet to a diamond + /// @param fsData contains function selectors of the facet + /// @param _facetAddress facet t0 be added + function addFacet( + FacetAndSelectorData storage fsData, + address _facetAddress + ) internal { enforceHasContractCode(_facetAddress); - fsData.facetFunctionSelectors[_facetAddress].facetAddressPosition = fsData - .facetAddresses - .length; + fsData + .facetFunctionSelectors[_facetAddress] + .facetAddressPosition = fsData.facetAddresses.length; fsData.facetAddresses.push(_facetAddress); } + /// @dev adds a functions to a selected facet + /// @param fsData the details of the facet + /// @param _selector of the functions to be added + /// _facetAddress of the function function addFunction( FacetAndSelectorData storage fsData, bytes4 _selector, @@ -197,9 +235,12 @@ function vaultFactory() internal view returns(address){ fsData.facetFunctionSelectors[_facetAddress].functionSelectors.push( _selector ); - fsData.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress; + fsData + .selectorToFacetAndPosition[_selector] + .facetAddress = _facetAddress; } + /// @notice removes a function from a a facet function removeFunction( FacetAndSelectorData storage fsData, address _facetAddress, @@ -255,9 +296,11 @@ function vaultFactory() internal view returns(address){ } } - function initializeDiamondCut(address _init, bytes memory _calldata) - internal - { + /// @notice initialise a diamond address + function initializeDiamondCut( + address _init, + bytes memory _calldata + ) internal { if (_init == address(0)) { if (_calldata.length > 0) revert NonEmptyCalldata(); } else { @@ -277,6 +320,7 @@ function vaultFactory() internal view returns(address){ } } + /// @notice checks if an addreess is a conttract function enforceHasContractCode(address _contract) internal view { uint256 contractSize; assembly { diff --git a/contracts/Vault/libraries/LibErrors.sol b/contracts/Vault/libraries/LibErrors.sol index f586657..034dd14 100644 --- a/contracts/Vault/libraries/LibErrors.sol +++ b/contracts/Vault/libraries/LibErrors.sol @@ -1,9 +1,8 @@ pragma solidity 0.8.4; - //list of shared Errors across Modules -library LibErrors{ -error LengthMismatch(); -error EmptyArray(); -error NoPermissions(); -} \ No newline at end of file +library LibErrors { + error LengthMismatch(); + error EmptyArray(); + error NoPermissions(); +} diff --git a/contracts/Vault/libraries/LibEther.sol b/contracts/Vault/libraries/LibEther.sol index 4320039..15b9a7d 100644 --- a/contracts/Vault/libraries/LibEther.sol +++ b/contracts/Vault/libraries/LibEther.sol @@ -8,18 +8,21 @@ import {LibDiamond} from "../libraries/LibDiamond.sol"; library LibEther { error InsufficientEth(); error EthWithdrawalError(); -error AmountMismatch(); + error AmountMismatch(); - event EthDeposited(uint256 _amount,address _from, uint256 _vaultID); - event EthWithdrawn(uint256 _amount,address _to, uint256 _vaultID); + event EthDeposited(uint256 _amount, address _from, uint256 _vaultID); + event EthWithdrawn(uint256 _amount, address _to, uint256 _vaultID); - function _depositEther(uint256 _amount) internal { + /// @notice allows caller to deposit ETH + /// @param _amount of ETH to be deposited ensures that _amount == msg.value + function _depositEther(uint256 _amount) internal { if (_amount != msg.value) { revert AmountMismatch(); } - emit EthDeposited(_amount,msg.sender, LibDiamond.vaultID()); + emit EthDeposited(_amount, msg.sender, LibDiamond.vaultID()); } + /// @dev allow caller to withdraw ETH if _amount is not greater than available ether function _withdrawEth(uint256 _amount, address _to) internal { //confirm free eth is sufficient uint256 availableEther = address(this).balance; @@ -30,13 +33,11 @@ error AmountMismatch(); if (_amount > availableEther) revert InsufficientEth(); } if (availableEther >= _amount) { - (bool success,) = _to.call{value: _amount}(""); + (bool success, ) = _to.call{value: _amount}(""); assert(success); } else { revert EthWithdrawalError(); } - emit EthWithdrawn(_amount,_to, LibDiamond.vaultID()); + emit EthWithdrawn(_amount, _to, LibDiamond.vaultID()); } - - } diff --git a/contracts/Vault/libraries/LibGuards.sol b/contracts/Vault/libraries/LibGuards.sol index 2f80514..b12c848 100644 --- a/contracts/Vault/libraries/LibGuards.sol +++ b/contracts/Vault/libraries/LibGuards.sol @@ -6,6 +6,7 @@ import "../libraries/LibLayoutSilo.sol"; import "../libraries/LibStorageBinder.sol"; library LibGuards { + /// @notice ensure that caller is vault owner function _onlyVaultOwner() internal view { LibDiamond.enforceIsContractOwner(); } diff --git a/contracts/Vault/libraries/LibLayoutSilo.sol b/contracts/Vault/libraries/LibLayoutSilo.sol index e096fb7..1b3570d 100644 --- a/contracts/Vault/libraries/LibLayoutSilo.sol +++ b/contracts/Vault/libraries/LibLayoutSilo.sol @@ -2,24 +2,25 @@ pragma solidity 0.8.4; //A record of data layouts...these are immutable and cannot be extended - ///DIAMOND_FACET_SELECTOR ////START///// struct FacetAddressAndPosition { address facetAddress; uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array } + struct FacetFunctionSelectors { bytes4[] functionSelectors; uint256 facetAddressPosition; // position of facetAddress in facetAddresses array } + struct FacetAndSelectorData { // maps function selector to the facet address and // the position of the selector in the facetFunctionSelectors.selectors array mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition; // maps facet addresses to function selectors mapping(address => FacetFunctionSelectors) facetFunctionSelectors; - // Used to query if a contract implements an interface. + // Used to query if a contract implements an interface. // Used to implement ERC-165. mapping(bytes4 => bool) supportedInterfaces; // facet addresses @@ -29,13 +30,15 @@ struct FacetAndSelectorData { // owner of the vault address vaultOwner; //Modules + // module's status mapping(string => bool) activeModule; - mapping(string=>uint256) moduleStorageCounter; + /// maps Module to counter + mapping(string => uint256) moduleStorageCounter; + // arrays of active modules string[] activeModules; } /////STOP///// - //DMS_GLOB_DATA ////START//// struct DMSData { @@ -56,20 +59,26 @@ struct DMSData { mapping(address => mapping(address => uint256)) inheritorTokenShares; //address of tokens allocated mapping(address => address[]) inheritorAllocatedERC20Tokens; + //ERC721 + // maps token address to inheritor mapping(address => mapping(address => bool)) whitelist; + // maps number of ERC721 token aloocated to inheritor mapping(address => mapping(address => uint256)) inheritorERC721Tokens; + // maps an address to token and inheritor mapping(address => mapping(uint256 => address)) ERC721ToInheritor; + // allocated ERC721 tokens mapping(address => mapping(uint256 => bool)) allocatedERC721Tokens; + // Erc721 tokens allocated to an inheritor mapping(address => address[]) inheritorAllocatedERC721TokenAddresses; + //ERC1155 + // maps token address and id to inheritor mapping(address => mapping(address => mapping(uint256 => uint256))) inheritorERC1155TokenAllocations; mapping(address => address[]) inheritorAllocatedERC1155TokenAddresses; //GLOBAL + // total tokens Id's allocated to an inheritor mapping(address => mapping(address => uint256[])) inheritorAllocatedTokenIds; mapping(address => bool) claimed; } ////STOP//// - - - diff --git a/contracts/Vault/libraries/LibModuleManager.sol b/contracts/Vault/libraries/LibModuleManager.sol index bb99a97..16675a9 100644 --- a/contracts/Vault/libraries/LibModuleManager.sol +++ b/contracts/Vault/libraries/LibModuleManager.sol @@ -4,9 +4,9 @@ import {FacetAndSelectorData} from "../libraries/LibLayoutSilo.sol"; import {LibStorageBinder} from "../libraries/LibStorageBinder.sol"; library LibModuleManager { - -function _isActiveModule(string memory _name) internal view returns(bool active_){ -FacetAndSelectorData storage fs=LibStorageBinder._bindAndReturnFacetStorage(); -active_=fs.activeModule[_name]; -} -} \ No newline at end of file + /// @notice checks if the module parsed in with _name is active + function _isActiveModule(string memory _name) internal view returns (bool active_) { + FacetAndSelectorData storage fs = LibStorageBinder._bindAndReturnFacetStorage(); + active_ = fs.activeModule[_name]; + } +} diff --git a/contracts/Vault/libraries/LibModuleUpgrades.sol b/contracts/Vault/libraries/LibModuleUpgrades.sol index dc5e726..24a846f 100644 --- a/contracts/Vault/libraries/LibModuleUpgrades.sol +++ b/contracts/Vault/libraries/LibModuleUpgrades.sol @@ -24,7 +24,8 @@ library LibModuleUpgrades { * address _vault* */ event VaultDowngraded(string indexed _moduleName); - + + /// @notice allows a vault to be upgraded by adding a module function _upgradeVaultWithModule(string calldata _name) internal { LibDiamond.enforceIsContractOwner(); //make sure this module doesn't currently exist in this vault @@ -43,6 +44,7 @@ library LibModuleUpgrades { //consider gossiping this upgrade to vaultFactory } + /// @notice allows vault to be downgraded by removing module function _downgradeVaultWithModule(string calldata _name) internal { LibDiamond.enforceIsContractOwner(); //make sure this module doesn't currently exist in this vault diff --git a/contracts/Vault/libraries/LibStorageBinder.sol b/contracts/Vault/libraries/LibStorageBinder.sol index 4fc1268..259a62e 100644 --- a/contracts/Vault/libraries/LibStorageBinder.sol +++ b/contracts/Vault/libraries/LibStorageBinder.sol @@ -1,7 +1,7 @@ pragma solidity 0.8.4; //import "../VaultDiamond.sol"; -import {FacetAndSelectorData,DMSData} from "../libraries/LibLayoutSilo.sol"; +import {FacetAndSelectorData, DMSData} from "../libraries/LibLayoutSilo.sol"; import "../facets/DiamondCutFacet.sol"; import "../facets/DiamondLoupeFacet.sol"; import "../facets/ERC1155Facet.sol"; @@ -9,23 +9,21 @@ import "../facets/ERC721Facet.sol"; import "../facets/ERC20Facet.sol"; import "../facets/DMSFacet.sol"; - //~(keccak256(abi.encode(slot,200))) library LibStorageBinder { - bytes32 constant SLOT_SALT = keccak256('storage_offset_salt'); + bytes32 constant SLOT_SALT = keccak256("storage_offset_salt"); + + /// @notice gets the location where a facet is stored + function _getStorageSlot(string memory _facetName1) internal pure returns (bytes32 slot) { + slot = keccak256(bytes(_facetName1)); + } - function _getStorageSlot(string memory _facetName1) + /// @notice returns slot of two facets + function _getStorageSlot(string memory _facetName1, string memory _facetName2) internal pure returns (bytes32 slot) { - slot = keccak256(bytes(_facetName1)); - } - - function _getStorageSlot( - string memory _facetName1, - string memory _facetName2 - ) internal pure returns (bytes32 slot) { slot = keccak256(bytes(abi.encode(_facetName1, _facetName2))); } // function _getStorageSlot( @@ -38,31 +36,18 @@ library LibStorageBinder { // slot = keccak256(bytes(abi.encode(_facetName1, _facetName2,_facetName3,_facetName4,_facetName5))); // } - function _bindAndReturnFacetStorage() - internal - pure - returns (FacetAndSelectorData storage selectorData) - { - bytes32 _slot = _getStorageSlot( - type(DiamondCutFacet).name, - type(DiamondLoupeFacet).name - ); + /// @notice binds a facet to its storage slot from the diamon loupe facet + function _bindAndReturnFacetStorage() internal pure returns (FacetAndSelectorData storage selectorData) { + bytes32 _slot = _getStorageSlot(type(DiamondCutFacet).name, type(DiamondLoupeFacet).name); bytes32 saltedOffset = _slot ^ SLOT_SALT; assembly { selectorData.slot := saltedOffset } } -function _bindAndReturnDMSStorage() - internal - pure - returns (DMSData storage vaultData) - { - bytes32 _slot = _getStorageSlot( - type(DiamondCutFacet).name, - type(DMSFacet).name - - ); + /// @notice binds vault Data to a slot from DMS facet + function _bindAndReturnDMSStorage() internal pure returns (DMSData storage vaultData) { + bytes32 _slot = _getStorageSlot(type(DiamondCutFacet).name, type(DMSFacet).name); bytes32 saltedOffset = _slot ^ SLOT_SALT; assembly { vaultData.slot := saltedOffset diff --git a/contracts/Vault/libraries/LibTokens.sol b/contracts/Vault/libraries/LibTokens.sol index f017f06..001b568 100644 --- a/contracts/Vault/libraries/LibTokens.sol +++ b/contracts/Vault/libraries/LibTokens.sol @@ -23,60 +23,24 @@ library LibTokens { event ERC20ErrorHandled(address); event ERC721ErrorHandled(address); - event ERC20TokenDeposit( - address indexed token, - address indexed from, - uint256 amount, - uint256 vaultID - ); - event ERC20TokenWithdrawal( - address token, - uint256 amount, - address to, - uint256 vaultID - ); + event ERC20TokenDeposit(address indexed token, address indexed from, uint256 amount, uint256 vaultID); + event ERC20TokenWithdrawal(address token, uint256 amount, address to, uint256 vaultID); - event ERC721TokenDeposit( - address indexed token, - address indexed from, - uint256 tokenID, - uint256 vaultID - ); - event ERC721TokenWIthdrawal( - address token, - uint256 tokenID, - address to, - uint256 vaultID - ); + event ERC721TokenDeposit(address indexed token, address indexed from, uint256 tokenID, uint256 vaultID); + event ERC721TokenWIthdrawal(address token, uint256 tokenID, address to, uint256 vaultID); event ERC1155TokenDeposit( - address indexed token, - address indexed from, - uint256 tokenID, - uint256 amount, - uint256 vaultID - ); - event ERC1155TokenWithdrawal( - address token, - uint256 tokenID, - uint256 amount, - address to, - uint256 vaultID + address indexed token, address indexed from, uint256 tokenID, uint256 amount, uint256 vaultID ); + event ERC1155TokenWithdrawal(address token, uint256 tokenID, uint256 amount, address to, uint256 vaultID); event BatchERC1155TokenDeposit( - address indexed token, - address indexed from, - uint256[] tokenIDs, - uint256[] amounts, - uint256 vaultID + address indexed token, address indexed from, uint256[] tokenIDs, uint256[] amounts, uint256 vaultID ); //ERC20 - function _inputERC20Tokens( - address[] calldata _tokenDeps, - uint256[] calldata _amounts - ) internal { + /// @notice allows caller to deposit several tokens to the vault with the respective amounts + function _inputERC20Tokens(address[] calldata _tokenDeps, uint256[] calldata _amounts) internal { if (_tokenDeps.length == 0 || _amounts.length == 0) { revert LibErrors.EmptyArray(); } @@ -91,12 +55,7 @@ library LibTokens { success; } catch { if (success) { - emit ERC20TokenDeposit( - token, - msg.sender, - amount, - LibDiamond.vaultID() - ); + emit ERC20TokenDeposit(token, msg.sender, amount, LibDiamond.vaultID()); } else { emit ErrorHandled(token); continue; @@ -105,21 +64,14 @@ library LibTokens { } } + /// @notice deposit a token to the vault contract function _inputERC20Token(address _token, uint256 _amount) internal { assert(IERC20(_token).transferFrom(msg.sender, address(this), _amount)); - emit ERC20TokenDeposit( - _token, - msg.sender, - _amount, - LibDiamond.vaultID() - ); + emit ERC20TokenDeposit(_token, msg.sender, _amount, LibDiamond.vaultID()); } - function _approveERC20Token( - address _spender, - address _token, - uint256 _amount - ) internal { + /// @notice caller approves spender to use amount of tokens + function _approveERC20Token(address _spender, address _token, uint256 _amount) internal { IERC20(_token).approve(_spender, _amount); //ping if DMS is installed if (LibModuleManager._isActiveModule("DMS")) { @@ -127,11 +79,8 @@ library LibTokens { } } - function _withdrawERC20Token( - address _token, - uint256 _amount, - address _to - ) internal { + /// @notice allows caller to withdraw unallocated ether in the vault + function _withdrawERC20Token(address _token, uint256 _amount, address _to) internal { uint256 availableTokens; uint256 currentBalance = IERC20(_token).balanceOf(address(this)); //check if DMS module is installed @@ -156,12 +105,7 @@ library LibTokens { success; } catch { if (success) { - emit ERC20TokenWithdrawal( - _token, - _amount, - _to, - LibDiamond.vaultID() - ); + emit ERC20TokenWithdrawal(_token, _amount, _to, LibDiamond.vaultID()); } else { emit ERC20ErrorHandled(_token); } @@ -171,11 +115,8 @@ library LibTokens { } } - function _withdrawERC20Tokens( - address[] calldata _tokenAdds, - uint256[] calldata _amounts, - address _to - ) internal { + /// @notice alows caller to withdraw tokens that haven't been allocated + function _withdrawERC20Tokens(address[] calldata _tokenAdds, uint256[] calldata _amounts, address _to) internal { if (_tokenAdds.length == 0 || _amounts.length == 0) { revert LibErrors.EmptyArray(); } @@ -208,12 +149,7 @@ library LibTokens { success; } catch { if (success) { - emit ERC20TokenWithdrawal( - token, - amount, - _to, - LibDiamond.vaultID() - ); + emit ERC20TokenWithdrawal(token, amount, _to, LibDiamond.vaultID()); } else { emit ERC20ErrorHandled(token); } @@ -224,80 +160,49 @@ library LibTokens { } } + /// @notice allows user to transfer ERC721 tokens to the vault //ERC721 function _inputERC721Token(address _token, uint256 _tokenID) internal { IERC721(_token).transferFrom(msg.sender, address(this), _tokenID); - emit ERC721TokenDeposit( - _token, - msg.sender, - _tokenID, - LibDiamond.vaultID() - ); + emit ERC721TokenDeposit(_token, msg.sender, _tokenID, LibDiamond.vaultID()); } - + /// @notice allows user to deposut ERC721 tokens to the vault via the safeTransferFrom method function _safeInputERC721Token(address _token, uint256 _tokenID) internal { IERC721(_token).safeTransferFrom(msg.sender, address(this), _tokenID); - emit ERC721TokenDeposit( - _token, - msg.sender, - _tokenID, - LibDiamond.vaultID() - ); + emit ERC721TokenDeposit(_token, msg.sender, _tokenID, LibDiamond.vaultID()); } - - function _safeInputERC721TokenAndCall( - address _token, - uint256 _tokenID, - bytes calldata _data - ) internal { - IERC721(_token).safeTransferFrom( - msg.sender, - address(this), - _tokenID, - _data - ); + /// @notice allows user to deposut ERC721 tokens to the vault + /// and pass data alongside + function _safeInputERC721TokenAndCall(address _token, uint256 _tokenID, bytes calldata _data) internal { + IERC721(_token).safeTransferFrom(msg.sender, address(this), _tokenID, _data); } - function _approveERC721Token( - address _token, - uint256 _tokenID, - address _to - ) internal { + /// @notice approves _to to spend specific token ID + function _approveERC721Token(address _token, uint256 _tokenID, address _to) internal { IERC721(_token).approve(_to, _tokenID); } - function _approveAllERC721Token( - address _token, - address _to, - bool _approved - ) internal { + /// @notice set approval for all token ID's of the token + function _approveAllERC721Token(address _token, address _to, bool _approved) internal { IERC721(_token).setApprovalForAll(_to, _approved); } - function _withdrawERC721Token( - address _token, - uint256 _tokenID, - address _to - ) internal { + /// @notice allows caller to withdraw a token ID + function _withdrawERC721Token(address _token, uint256 _tokenID, address _to) internal { if (IERC721(_token).ownerOf(_tokenID) != address(this)) { revert NotERC721Owner(); } if (LibModuleManager._isActiveModule("DMS")) { - if (LibDMS._isERC721Allocated(_token, _tokenID)) + if (LibDMS._isERC721Allocated(_token, _tokenID)) { revert("UnAllocate Token First"); + } LibDMS._ping(); } - try - IERC721(_token).safeTransferFrom(address(this), _to, _tokenID) - {} catch { + try IERC721(_token).safeTransferFrom(address(this), _to, _tokenID) {} + catch { string memory reason; if (bytes(reason).length == 0) { - emit ERC721TokenWIthdrawal( - _token, - _tokenID, - _to, - LibDiamond.vaultID() - ); + emit ERC721TokenWIthdrawal(_token, _tokenID, _to, LibDiamond.vaultID()); } else { emit ERC721ErrorHandled(_token); } @@ -305,73 +210,31 @@ library LibTokens { } //ERC1155 - - function _safeInputERC1155Token( - address _token, - uint256 _tokenID, - uint256 _value - ) internal { - IERC1155(_token).safeTransferFrom( - msg.sender, - address(this), - _tokenID, - _value, - "" - ); - emit ERC1155TokenDeposit( - _token, - msg.sender, - _tokenID, - _value, - LibDiamond.vaultID() - ); + /// aloows caller to deposit a unit of ERC1155 to the vault + function _safeInputERC1155Token(address _token, uint256 _tokenID, uint256 _value) internal { + IERC1155(_token).safeTransferFrom(msg.sender, address(this), _tokenID, _value, ""); + emit ERC1155TokenDeposit(_token, msg.sender, _tokenID, _value, LibDiamond.vaultID()); } - function _safeBatchInputERC1155Tokens( - address _token, - uint256[] calldata _tokenIDs, - uint256[] calldata _values - ) internal { - IERC1155(_token).safeBatchTransferFrom( - msg.sender, - address(this), - _tokenIDs, - _values, - "" - ); - emit BatchERC1155TokenDeposit( - _token, - msg.sender, - _tokenIDs, - _values, - LibDiamond.vaultID() - ); + /// @notice allows deposits of multiple Id's of ERC1155 token to the vault + function _safeBatchInputERC1155Tokens(address _token, uint256[] calldata _tokenIDs, uint256[] calldata _values) + internal + { + IERC1155(_token).safeBatchTransferFrom(msg.sender, address(this), _tokenIDs, _values, ""); + emit BatchERC1155TokenDeposit(_token, msg.sender, _tokenIDs, _values, LibDiamond.vaultID()); } - function _approveAllERC1155Token( - address _token, - address _to, - bool _approved - ) internal { + /// @notice caller approves _to to spend all tokens + function _approveAllERC1155Token(address _token, address _to, bool _approved) internal { IERC1155(_token).setApprovalForAll(_to, _approved); } - function _withdrawERC1155Token( - address _token, - uint256 _tokenID, - uint256 _amount, - address _to - ) internal { - uint256 currentBalance = IERC1155(_token).balanceOf( - address(this), - _tokenID - ); + /// @notice allow user to withdraw a unit of ERC1155 token + function _withdrawERC1155Token(address _token, uint256 _tokenID, uint256 _amount, address _to) internal { + uint256 currentBalance = IERC1155(_token).balanceOf(address(this), _tokenID); uint256 availableTokens; if (LibModuleManager._isActiveModule("DMS")) { - uint256 allocated = LibDMS.getCurrentAllocated1155tokens( - _token, - _tokenID - ); + uint256 allocated = LibDMS.getCurrentAllocated1155tokens(_token, _tokenID); if (currentBalance > allocated) { availableTokens = currentBalance - allocated; LibDMS._ping(); @@ -391,19 +254,7 @@ library LibTokens { revert InsufficientTokens(); } - IERC1155(_token).safeTransferFrom( - address(this), - _to, - _tokenID, - _amount, - "" - ); - emit ERC1155TokenWithdrawal( - _token, - _tokenID, - _amount, - _to, - LibDiamond.vaultID() - ); + IERC1155(_token).safeTransferFrom(address(this), _to, _tokenID, _amount, ""); + emit ERC1155TokenWithdrawal(_token, _tokenID, _amount, _to, LibDiamond.vaultID()); } } diff --git a/contracts/VaultFactory/VaultFactoryDiamond.sol b/contracts/VaultFactory/VaultFactoryDiamond.sol index c2d5b60..c07d657 100644 --- a/contracts/VaultFactory/VaultFactoryDiamond.sol +++ b/contracts/VaultFactory/VaultFactoryDiamond.sol @@ -2,10 +2,6 @@ pragma solidity ^0.8.0; /** - * \ - * Author: Nick Mudge (https://twitter.com/mudgen) - * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 - * * Implementation of a diamond. * /***************************************************************************** */ @@ -15,7 +11,12 @@ import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; import "./libraries/LibFactoryAppStorage.sol"; +// struct Facet { +// address facetAddress; +// bytes4[] functionSelectors; +// } contract VaultFactoryDiamond { + /// @notice sts contract owner and the diamond cut facet constructor(address _contractOwner, address _diamondCutFacet) payable { LibFactoryDiamond.setContractOwner(_contractOwner); @@ -31,10 +32,10 @@ contract VaultFactoryDiamond { LibFactoryDiamond.diamondCut(cut, address(0), ""); } - - + /// @notice returns contract owner function owner() public view returns (address owner_) { - LibFactoryDiamond.DiamondStorage storage ds = LibFactoryDiamond.diamondStorage(); + LibFactoryDiamond.DiamondStorage storage ds = LibFactoryDiamond + .diamondStorage(); owner_ = ds.contractOwner; } @@ -60,8 +61,12 @@ contract VaultFactoryDiamond { returndatacopy(0, 0, returndatasize()) // return any return value or error back to the caller switch result - case 0 { revert(0, returndatasize()) } - default { return(0, returndatasize()) } + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } } } diff --git a/contracts/VaultFactory/facets/DiamondLoupeFactoryFacet.sol b/contracts/VaultFactory/facets/DiamondLoupeFactoryFacet.sol index d96cc48..f50ce3c 100644 --- a/contracts/VaultFactory/facets/DiamondLoupeFactoryFacet.sol +++ b/contracts/VaultFactory/facets/DiamondLoupeFactoryFacet.sol @@ -15,11 +15,6 @@ contract DiamondLoupeFactoryFacet is IDiamondLoupe, IERC165 { // Diamond Loupe Functions //////////////////////////////////////////////////////////////////// /// These functions are expected to be called frequently by tools. - // - // struct Facet { - // address facetAddress; - // bytes4[] functionSelectors; - // } /// @notice Gets all facets and their selectors. /// @return facets_ Facet diff --git a/contracts/VaultFactory/facets/ModuleRegistryFacet.sol b/contracts/VaultFactory/facets/ModuleRegistryFacet.sol index 6749ce5..689be3a 100644 --- a/contracts/VaultFactory/facets/ModuleRegistryFacet.sol +++ b/contracts/VaultFactory/facets/ModuleRegistryFacet.sol @@ -7,22 +7,29 @@ import {IModuleData} from "../../interfaces/IModuleData.sol"; import {IDiamondCut} from "../../interfaces/IDiamondCut.sol"; contract ModuleRegistryFacet is StorageLayout { + /// @notice add modules to the registry + /// @param _modules to be added + /// @param _names of modules function addModules(IModuleData.ModuleData[] calldata _modules, string[] calldata _names) external { LibModuleRegistry._addModules(_modules, _names); } + /// @notice returns the details multiple modules stored in the registry function getModules(string[] calldata _names) external view returns (IModuleData.ModuleData[] memory modules_) { modules_ = LibModuleRegistry._getModules(_names); } + /// @notice gets the details of a specific module from regigistry function getModule(string calldata _name) external view returns (IModuleData.ModuleData memory module_) { module_ = LibModuleRegistry._getModule(_name); } + /// @dev returns the facet cuts attached to a module function getFacetCuts(string memory _name) external view returns (IDiamondCut.FacetCut[] memory cuts_) { cuts_ = LibModuleRegistry._getFacetCuts(_name); } + /// Checks if a module extist, returns false if module is not found function moduleExists(string calldata _name) external view returns (bool exists_) { exists_ = LibModuleRegistry._moduleExists(_name); } diff --git a/contracts/VaultFactory/facets/VaultSpawnerFacet.sol b/contracts/VaultFactory/facets/VaultSpawnerFacet.sol index 5411bc2..9e62c2c 100644 --- a/contracts/VaultFactory/facets/VaultSpawnerFacet.sol +++ b/contracts/VaultFactory/facets/VaultSpawnerFacet.sol @@ -10,19 +10,14 @@ import "../../interfaces/IVaultFacet.sol"; import {FactoryAppStorage, StorageLayout} from "../libraries/LibFactoryAppStorage.sol"; contract VaultSpawnerFacet is StorageLayout { - event VaultCreated( - address indexed owner, - uint256 indexed startingBalance, - uint256 vaultID - ); + event VaultCreated(address indexed owner, uint256 indexed startingBalance, uint256 vaultID); error BackupAddressError(); - - function createVault(address _vaultOwner, uint256 _startingBal) - external - payable - returns (address addr) - { + + /// @notice creates vault attached with token and selector modules + /// @param _vaultOwner address to be set + /// @param _startingBal of the vault which must be sent in the same transaction + function createVault(address _vaultOwner, uint256 _startingBal) external payable returns (address addr) { if (_startingBal > 0) { assert(_startingBal == msg.value); } @@ -30,12 +25,8 @@ contract VaultSpawnerFacet is StorageLayout { bytes32 entropy = keccak256(abi.encode(_vaultOwner, fs.VAULTID)); //get Selector and Token Module FacetCuts - IDiamondCut.FacetCut[] storage selectorModuleCut = fs - .masterModules["Selector"] - .facetData; - IDiamondCut.FacetCut[] storage tokenModuleCut = fs - .masterModules["Token"] - .facetData; + IDiamondCut.FacetCut[] storage selectorModuleCut = fs.masterModules["Selector"].facetData; + IDiamondCut.FacetCut[] storage tokenModuleCut = fs.masterModules["Token"].facetData; VaultDiamond vDiamond = new VaultDiamond{ salt: entropy, diff --git a/contracts/VaultFactory/libraries/LibFactoryAppStorage.sol b/contracts/VaultFactory/libraries/LibFactoryAppStorage.sol index e36b69a..75ffbec 100644 --- a/contracts/VaultFactory/libraries/LibFactoryAppStorage.sol +++ b/contracts/VaultFactory/libraries/LibFactoryAppStorage.sol @@ -2,11 +2,12 @@ pragma solidity 0.8.4; import "../../Vault/libraries/LibArrayHelpers.sol"; import {IModuleData} from "../../interfaces/IModuleData.sol"; + struct FactoryAppStorage { //master vaultID uint256 VAULTID; //human readable names to Module data - mapping(string=>IModuleData.ModuleData) masterModules; + mapping(string => IModuleData.ModuleData) masterModules; } library LibFactoryAppStorage { diff --git a/contracts/VaultFactory/libraries/LibFactoryDiamond.sol b/contracts/VaultFactory/libraries/LibFactoryDiamond.sol index 9204a56..8b51751 100644 --- a/contracts/VaultFactory/libraries/LibFactoryDiamond.sol +++ b/contracts/VaultFactory/libraries/LibFactoryDiamond.sol @@ -49,6 +49,7 @@ library LibFactoryDiamond { address contractOwner; } + /// @notice sets the slot where diamond is stored function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { @@ -58,6 +59,7 @@ library LibFactoryDiamond { event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + /// @notice sets address as the conttact owner function setContractOwner(address _newOwner) internal { DiamondStorage storage ds = diamondStorage(); address previousOwner = ds.contractOwner; @@ -65,10 +67,12 @@ library LibFactoryDiamond { emit OwnershipTransferred(previousOwner, _newOwner); } + /// @notice returns the address of current contract owner function contractOwner() internal view returns (address contractOwner_) { contractOwner_ = diamondStorage().contractOwner; } + /// @notice ensures that calller is contract owner function enforceIsContractOwner() internal view { if (msg.sender != diamondStorage().contractOwner) revert NotDiamondOwner(); } @@ -76,6 +80,12 @@ library LibFactoryDiamond { event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata); // Internal function version of diamondCut + + /// @notice Add/replace/remove any number of functions + /// @param _diamondCut Contains the facet addresses and function selectors + /// @param _init The address of the contract or facet to execute _calldata + /// @param _calldata A function call, including function selector and arguments + function diamondCut( IDiamondCut.FacetCut[] memory _diamondCut, address _init, @@ -97,6 +107,9 @@ library LibFactoryDiamond { initializeDiamondCut(_init, _calldata); } + /// @notice adds new functions to a facet + /// @param _facetAddress facet where the function will be added + /// @param _functionSelectors arrays of functions to be added function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { if (_functionSelectors.length <= 0) revert NoSelectorsInFacet(); DiamondStorage storage ds = diamondStorage(); @@ -114,7 +127,7 @@ library LibFactoryDiamond { selectorPosition++; } } - + /// @notice replaces functions in a selected facet function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { if (_functionSelectors.length <= 0) revert NoSelectorsInFacet(); DiamondStorage storage ds = diamondStorage(); @@ -134,6 +147,7 @@ library LibFactoryDiamond { } } + /// @notice removes functions from a facet function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { if (_functionSelectors.length <= 0) revert NoSelectorsInFacet(); DiamondStorage storage ds = diamondStorage(); @@ -146,12 +160,16 @@ library LibFactoryDiamond { } } + /// @notice add facet to diamond function addFacet(DiamondStorage storage ds, address _facetAddress) internal { enforceHasContractCode(_facetAddress); ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length; ds.facetAddresses.push(_facetAddress); } + /// @dev adds a functions to a selected facet + /// @param _selector of the functions to be added + /// _facetAddress of the function function addFunction( DiamondStorage storage ds, bytes4 _selector, @@ -163,6 +181,7 @@ library LibFactoryDiamond { ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress; } + /// @notice removes a function from a a facet function removeFunction( DiamondStorage storage ds, address _facetAddress, @@ -199,6 +218,7 @@ library LibFactoryDiamond { } } + /// initilize diamond cut with associated calldata function initializeDiamondCut(address _init, bytes memory _calldata) internal { if (_init == address(0)) { if (_calldata.length > 0) revert NonEmptyCalldata(); @@ -218,7 +238,7 @@ library LibFactoryDiamond { } } } - + /// @notice ensures that address is a contract type function enforceHasContractCode(address _contract) internal view { uint256 contractSize; assembly { diff --git a/contracts/VaultFactory/libraries/LibModuleRegistry.sol b/contracts/VaultFactory/libraries/LibModuleRegistry.sol index f4adeea..1c10f6e 100644 --- a/contracts/VaultFactory/libraries/LibModuleRegistry.sol +++ b/contracts/VaultFactory/libraries/LibModuleRegistry.sol @@ -12,8 +12,10 @@ error NonExistentModule(string moduleName); library LibModuleRegistry { event ModuleAdded(string indexed _name, IModuleData.ModuleData _module); - //allow Proxy Factory admin(multisig) to add modules to Module Registry + //allow Proxy Factory admin(multisig) to add modules to Module Registry + /// @param _modules data to be registered + /// @param _names of modules to be regustered function _addModules(IModuleData.ModuleData[] calldata _modules, string[] calldata _names) internal { assert(_modules.length == _names.length); LibFactoryDiamond.enforceIsContractOwner(); @@ -26,8 +28,9 @@ library LibModuleRegistry { emit ModuleAdded(_names[i], _modules[i]); } } - //to-do _removeModules + //TODO: _removeModules + /// @notice get the details of modules function _getModules(string[] memory _names) internal view returns (IModuleData.ModuleData[] memory modules_) { modules_ = new IModuleData.ModuleData[](_names.length); for (uint256 i = 0; i < _names.length; i++) { @@ -35,6 +38,8 @@ library LibModuleRegistry { } } + /// @notice checks for details of a specific module + /// reverrts if module does not exist function _getModule(string memory _name) internal view returns (IModuleData.ModuleData memory module_) { FactoryAppStorage storage fs = LibFactoryAppStorage.factoryAppStorage(); IModuleData.ModuleData storage m = fs.masterModules[_name]; @@ -42,6 +47,8 @@ library LibModuleRegistry { module_ = m; } + /// @notice returns the facet cuts attached to a module + /// reverts if module parsed in with _name does not exist function _getFacetCuts(string memory _name) internal view returns (IDiamondCut.FacetCut[] memory cuts_) { FactoryAppStorage storage fs = LibFactoryAppStorage.factoryAppStorage(); IModuleData.ModuleData storage m = fs.masterModules[_name]; @@ -49,6 +56,7 @@ library LibModuleRegistry { cuts_ = fs.masterModules[_name].facetData; } + /// @notice checks if a module exist, returns false if its not available function _moduleExists(string memory _name) internal view returns (bool exists_) { FactoryAppStorage storage fs = LibFactoryAppStorage.factoryAppStorage(); IModuleData.ModuleData storage m = fs.masterModules[_name]; diff --git a/contracts/interfaces/IDiamondCut.sol b/contracts/interfaces/IDiamondCut.sol index 2972f69..c83cfce 100644 --- a/contracts/interfaces/IDiamondCut.sol +++ b/contracts/interfaces/IDiamondCut.sol @@ -1,13 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -/******************************************************************************\ -* Author: Nick Mudge (https://twitter.com/mudgen) -* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 -/******************************************************************************/ +/** + * \ + * Author: Nick Mudge + * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 + * /***************************************************************************** + */ interface IDiamondCut { - enum FacetCutAction {Add, Replace, Remove} + enum FacetCutAction { + Add, + Replace, + Remove + } // Add=0, Replace=1, Remove=2 struct FacetCut { @@ -22,11 +28,7 @@ interface IDiamondCut { /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init - function diamondCut( - FacetCut[] calldata _diamondCut, - address _init, - bytes calldata _calldata - ) external; + function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external; event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); } diff --git a/contracts/interfaces/IDiamondLoupe.sol b/contracts/interfaces/IDiamondLoupe.sol index c3b2570..1d9bc46 100644 --- a/contracts/interfaces/IDiamondLoupe.sol +++ b/contracts/interfaces/IDiamondLoupe.sol @@ -1,10 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -/******************************************************************************\ -* Author: Nick Mudge (https://twitter.com/mudgen) -* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 -/******************************************************************************/ +/** + * \ + * Author: Nick Mudge + * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 + * /***************************************************************************** + */ // A loupe is a small magnifying glass used to look at diamonds. // These functions look at diamonds diff --git a/contracts/interfaces/IERC1155.sol b/contracts/interfaces/IERC1155.sol index 8e49ec5..1920cc1 100644 --- a/contracts/interfaces/IERC1155.sol +++ b/contracts/interfaces/IERC1155.sol @@ -1,26 +1,35 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.4; + interface IERC1155 { - - event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value); - event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values); + event TransferSingle( + address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value + ); + event TransferBatch( + address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values + ); - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - event URI(string _value, uint256 indexed _id); - function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; - function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external; + function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data + ) external; function balanceOf(address _owner, uint256 _id) external view returns (uint256); - function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); + function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) + external + view + returns (uint256[] memory); function setApprovalForAll(address _operator, bool _approved) external; - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} \ No newline at end of file +} diff --git a/contracts/interfaces/IERC721.sol b/contracts/interfaces/IERC721.sol index d30ce0d..a52d908 100644 --- a/contracts/interfaces/IERC721.sol +++ b/contracts/interfaces/IERC721.sol @@ -1,40 +1,21 @@ pragma solidity 0.8.4; -interface IERC721{ -function balanceOf(address owner) external view returns (uint256 balance); - - function ownerOf(uint256 tokenId) external view returns (address owner); - - function safeTransferFrom( - address from, - address to, - uint256 tokenId, - bytes calldata data - ) external; - - function safeTransferFrom( - address from, - address to, - uint256 tokenId - ) external; - - function transferFrom( - address from, - address to, - uint256 tokenId - ) external; - - function approve(address to, uint256 tokenId) external; - - function setApprovalForAll(address operator, bool _approved) external; - - function getApproved(uint256 tokenId) - external - view - returns (address operator); - - function isApprovedForAll(address owner, address operator) - external - view - returns (bool); -} \ No newline at end of file +interface IERC721 { + function balanceOf(address owner) external view returns (uint256 balance); + + function ownerOf(uint256 tokenId) external view returns (address owner); + + function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; + + function safeTransferFrom(address from, address to, uint256 tokenId) external; + + function transferFrom(address from, address to, uint256 tokenId) external; + + function approve(address to, uint256 tokenId) external; + + function setApprovalForAll(address operator, bool _approved) external; + + function getApproved(uint256 tokenId) external view returns (address operator); + + function isApprovedForAll(address owner, address operator) external view returns (bool); +} diff --git a/contracts/interfaces/IModuleData.sol b/contracts/interfaces/IModuleData.sol index aa8bdd3..74fecb5 100644 --- a/contracts/interfaces/IModuleData.sol +++ b/contracts/interfaces/IModuleData.sol @@ -16,7 +16,8 @@ interface IModuleData { //human readable names of facets involved in alphabetical order string[] facetNames; } - + /// @notice returns acive modules in a vault function getActiveModules() external view returns (string[] memory); + /// @notice checks for the status of a module function isActiveModule(string memory _name) external view returns (bool exists_); } diff --git a/contracts/interfaces/IVaultDiamond.sol b/contracts/interfaces/IVaultDiamond.sol index 3251ef3..685cc69 100644 --- a/contracts/interfaces/IVaultDiamond.sol +++ b/contracts/interfaces/IVaultDiamond.sol @@ -1,11 +1,10 @@ pragma solidity 0.8.4; + import "../interfaces/IModuleData.sol"; interface IVaultDiamond { - function vaultFactoryDiamond() external view returns(address); + function vaultFactoryDiamond() external view returns (address); //via delegatecall on diamond function vaultOwner() external view returns (address); - - } diff --git a/contracts/interfaces/IVaultFacet.sol b/contracts/interfaces/IVaultFacet.sol index 1d7dacd..26ce71d 100644 --- a/contracts/interfaces/IVaultFacet.sol +++ b/contracts/interfaces/IVaultFacet.sol @@ -20,9 +20,10 @@ interface IVaultFacet { ); event EthDeposited(uint256 _amount, uint256 _vaultID); - + // adda inheritors and weishares to a vault function addInheritors(address[] calldata _newInheritors, uint256[] calldata _weiShare) external; - + // sets a new backup address function transferBackup(address _newBackupAddress) external; + /// @notice returns allocated ether in a a vault function allEtherAllocations() external view returns (AllInheritorEtherAllocs[] memory eAllocs); } diff --git a/contracts/interfaces/IVaultFactory.sol b/contracts/interfaces/IVaultFactory.sol index 239baa8..7d29a80 100644 --- a/contracts/interfaces/IVaultFactory.sol +++ b/contracts/interfaces/IVaultFactory.sol @@ -4,9 +4,19 @@ import {IModuleData} from "../interfaces/IModuleData.sol"; import {IDiamondCut} from "../interfaces/IDiamondCut.sol"; interface IVaultFactory { + /// @notice This is used to get the details of several modules + /// @param _names the name of the modules to be fetched function getModules(string[] memory _names) external view returns (IModuleData.ModuleData[] memory modules_); + + /// @notice used to get the details of a a single module + /// @param _name of the module function getModule(string calldata _name) external view returns (IModuleData.ModuleData memory module_); + /// @notice checks if a module exists + /// @param _name the name of the module to be checked function moduleExists(string calldata _name) external view returns (bool exists_); + + /// @notice return the cuts associated with a facet + /// @param _name of a facet function getFacetCuts(string memory _name) external view returns (IDiamondCut.FacetCut[] memory cuts_); } diff --git a/test/DMSFacetTests.t.sol b/test/DMSFacetTests.t.sol index 490022c..c94281c 100644 --- a/test/DMSFacetTests.t.sol +++ b/test/DMSFacetTests.t.sol @@ -18,28 +18,18 @@ contract DMSFacetTest is DDeployments { erc721t.setApprovalForAll(vault1, true); //deposit - v1ERC20Facet.depositERC20Tokens( - toSingletonAdd(address(erc20t)), - toSingletonUINT(100e18) - ); + v1ERC20Facet.depositERC20Tokens(toSingletonAdd(address(erc20t)), toSingletonUINT(100e18)); v1ERC721Facet.depositERC721Tokens(address(erc721t), toSingletonUINT(0)); - v1ERC1155Facet.batchDepositERC1155Tokens( - address(erc1155t), - toSingletonUINT(0), - toSingletonUINT(2) - ); + v1ERC1155Facet.batchDepositERC1155Tokens(address(erc1155t), toSingletonUINT(0), toSingletonUINT(2)); vm.stopPrank(); vm.startPrank(vault1Owner); //test inheritor addition and removal //add another inheritor - v1dmsFacet.addInheritors( - toSingletonAdd(vault1Inheritor2), - toSingletonUINT(1000 wei) - ); + v1dmsFacet.addInheritors(toSingletonAdd(vault1Inheritor2), toSingletonUINT(1000 wei)); DMSFacet.VaultInfo memory vInfo = v1dmsFacet.inspectVault(); assertEq(vInfo.inheritors.length, 2); @@ -50,25 +40,14 @@ contract DMSFacetTest is DDeployments { //allocate some erc20,erc721 and erc1155 tokens to an inheritor //erc20 - v1dmsFacet.allocateERC20Tokens( - address(erc20t), - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(100e18) - ); + v1dmsFacet.allocateERC20Tokens(address(erc20t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(100e18)); // //erc721 - v1dmsFacet.allocateERC721Tokens( - address(erc721t), - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(0) - ); + v1dmsFacet.allocateERC721Tokens(address(erc721t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(0)); // //erc1155 v1dmsFacet.allocateERC1155Tokens( - address(erc1155t), - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(0), - toSingletonUINT(2) + address(erc1155t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(0), toSingletonUINT(2) ); // //confirm allocations @@ -79,18 +58,9 @@ contract DMSFacetTest is DDeployments { v1dmsFacet.removeInheritors(toSingletonAdd(vault1Inheritor1)); //re-confirm allocations - assertEq( - v1dmsFacet.getAllAllocatedERC1155Tokens(vault1Inheritor1).length, - 0 - ); - assertEq( - v1dmsFacet.getAllocatedERC20Tokens(vault1Inheritor1).length, - 0 - ); - assertEq( - v1dmsFacet.getAllocatedERC721Tokens(vault1Inheritor1).length, - 0 - ); + assertEq(v1dmsFacet.getAllAllocatedERC1155Tokens(vault1Inheritor1).length, 0); + assertEq(v1dmsFacet.getAllocatedERC20Tokens(vault1Inheritor1).length, 0); + assertEq(v1dmsFacet.getAllocatedERC721Tokens(vault1Inheritor1).length, 0); vInfo = v1dmsFacet.inspectVault(); assertEq(vInfo.inheritors.length, 1); @@ -105,31 +75,17 @@ contract DMSFacetTest is DDeployments { vm.startPrank(newVault1Owner); // //add inheritor1 again and allocate - v1dmsFacet.addInheritors( - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(10000000 wei) - ); + v1dmsFacet.addInheritors(toSingletonAdd(vault1Inheritor1), toSingletonUINT(10000000 wei)); // //erc20 - v1dmsFacet.allocateERC20Tokens( - address(erc20t), - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(100e18) - ); + v1dmsFacet.allocateERC20Tokens(address(erc20t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(100e18)); // //erc721 - v1dmsFacet.allocateERC721Tokens( - address(erc721t), - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(0) - ); + v1dmsFacet.allocateERC721Tokens(address(erc721t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(0)); // //erc1155 v1dmsFacet.allocateERC1155Tokens( - address(erc1155t), - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(0), - toSingletonUINT(2) + address(erc1155t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(0), toSingletonUINT(2) ); vm.stopPrank(); diff --git a/test/DiamondDeployments.sol b/test/DiamondDeployments.sol index 4c7615c..3fef3f6 100644 --- a/test/DiamondDeployments.sol +++ b/test/DiamondDeployments.sol @@ -195,10 +195,7 @@ contract DDeployments is Test { selectorName[0] = "Selector"; selectorName[1] = "Token"; //Register Selector and Token Modules in Factory - ModuleRegistryFacet(address(vFactoryDiamond)).addModules( - data, - selectorName - ); + ModuleRegistryFacet(address(vFactoryDiamond)).addModules(data, selectorName); vault1Owner = mkaddr("vault1Owner"); vault1Inheritor1 = mkaddr("vault1Inheritor1"); @@ -206,9 +203,7 @@ contract DDeployments is Test { //make sure vault1Owner is tx.origin vm.prank(address(this), vault1Owner); - vault1 = VaultSpawnerFacet(address(vFactoryDiamond)).createVault{ - value: 1 ether - }(vault1Owner, 1e18); + vault1 = VaultSpawnerFacet(address(vFactoryDiamond)).createVault{value: 1 ether}(vault1Owner, 1e18); //Register DMS Module in factory diamond @@ -227,10 +222,7 @@ contract DDeployments is Test { string[] memory DMSselectorName = new string[](1); DMSselectorName[0] = "DMS"; - ModuleRegistryFacet(address(vFactoryDiamond)).addModules( - DMSdata, - DMSselectorName - ); + ModuleRegistryFacet(address(vFactoryDiamond)).addModules(DMSdata, DMSselectorName); //upgrade DMS Module Vault diamond vm.prank(vault1Owner); ModuleManagerFacet(address(vault1)).upgradeVaultWithModule("DMS"); @@ -244,10 +236,7 @@ contract DDeployments is Test { ownerFacet = OwnershipFacet(vault1); vm.prank(vault1Owner); - v1dmsFacet.addInheritors( - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(10000) - ); + v1dmsFacet.addInheritors(toSingletonAdd(vault1Inheritor1), toSingletonUINT(10000)); } function testDefaultModules() public { @@ -262,9 +251,7 @@ contract DDeployments is Test { ModuleManagerFacet(address(vault1)).upgradeVaultWithModule("Selector"); // downgrade an already exosting vault - ModuleManagerFacet(address(vault1)).downgradeVaultWithModule( - "Selector" - ); + ModuleManagerFacet(address(vault1)).downgradeVaultWithModule("Selector"); // vm.stopPrank(); } @@ -273,10 +260,7 @@ contract DDeployments is Test { ModuleManagerFacet(address(vault1)).isActiveModule("DMS"); } - function generateSelectors(string memory _facetName) - internal - returns (bytes4[] memory selectors) - { + function generateSelectors(string memory _facetName) internal returns (bytes4[] memory selectors) { string[] memory cmd = new string[](3); cmd[0] = "node"; cmd[1] = "scripts/genSelectors.js"; @@ -286,9 +270,7 @@ contract DDeployments is Test { } function mkaddr(string memory name) public returns (address) { - address addr = address( - uint160(uint256(keccak256(abi.encodePacked(name)))) - ); + address addr = address(uint160(uint256(keccak256(abi.encodePacked(name))))); vm.label(addr, name); return addr; } @@ -320,11 +302,7 @@ function toDualAdd(address _no, address _no2) pure returns (address[] memory) { return arr; } -function toTriUINT( - uint256 _no, - uint256 _no2, - uint256 _no3 -) pure returns (uint256[] memory) { +function toTriUINT(uint256 _no, uint256 _no2, uint256 _no3) pure returns (uint256[] memory) { uint256[] memory arr = new uint256[](3); arr[0] = _no; arr[1] = _no2; @@ -332,11 +310,7 @@ function toTriUINT( return arr; } -function toTriAddress( - address _add, - address _add2, - address _add3 -) pure returns (address[] memory) { +function toTriAddress(address _add, address _add2, address _add3) pure returns (address[] memory) { address[] memory arr = new address[](3); arr[0] = _add; arr[1] = _add2; diff --git a/test/ERC721FacetTest.t.sol b/test/ERC721FacetTest.t.sol index 2a90849..0fbe4f1 100644 --- a/test/ERC721FacetTest.t.sol +++ b/test/ERC721FacetTest.t.sol @@ -31,10 +31,7 @@ contract ERC721FacetTest is DDeployments { // deposit multiple tokens v1ERC721Facet.depositERC721Tokens(address(erc721t), toTriUINT(0, 1, 2)); - v1ERC721Facet.depositERC721Tokens( - address(erc721t2), - toTriUINT(0, 1, 2) - ); + v1ERC721Facet.depositERC721Tokens(address(erc721t2), toTriUINT(0, 1, 2)); //confirm deposit assertEq(erc721t.balanceOf(vault1), 3); @@ -45,24 +42,16 @@ contract ERC721FacetTest is DDeployments { // //ALLOCATIONS // //trying to allocate a non existent token should not revert the whole txn - v1dmsFacet.allocateERC721Tokens( - address(erc721t), - toSingletonAdd(vault1Inheritor1), - toSingletonUINT(9) - ); + v1dmsFacet.allocateERC721Tokens(address(erc721t), toSingletonAdd(vault1Inheritor1), toSingletonUINT(9)); // //trying to allocate a token not owned by the vault should not revert the whole txn v1dmsFacet.allocateERC721Tokens( - address(erc721t), - toDualAdd(vault1Inheritor1, vault1Inheritor1), - toDualUINT(0, 3) + address(erc721t), toDualAdd(vault1Inheritor1, vault1Inheritor1), toDualUINT(0, 3) ); // //confirm storage - DMSFacet.AllocatedERC721Tokens[] - memory vault1Inheritor1Alloc = v1dmsFacet.getAllocatedERC721Tokens( - vault1Inheritor1 - ); + DMSFacet.AllocatedERC721Tokens[] memory vault1Inheritor1Alloc = + v1dmsFacet.getAllocatedERC721Tokens(vault1Inheritor1); assertEq(vault1Inheritor1Alloc[0].token, address(erc721t)); assertEq(vault1Inheritor1Alloc[0].tokenIDs[0], 0); @@ -71,49 +60,25 @@ contract ERC721FacetTest is DDeployments { v1ERC721Facet.withdrawERC721Token(address(erc721t), 0, vault1Owner); // //add inheritor2 - v1dmsFacet.addInheritors( - toSingletonAdd(vault1Inheritor2), - toSingletonUINT(1000 wei) - ); + v1dmsFacet.addInheritors(toSingletonAdd(vault1Inheritor2), toSingletonUINT(1000 wei)); // //can easily reallocate tokens to inheritor2 - v1dmsFacet.allocateERC721Tokens( - address(erc721t), - toSingletonAdd(vault1Inheritor2), - toSingletonUINT(0) - ); - v1dmsFacet.allocateERC721Tokens( - address(erc721t), - toSingletonAdd(vault1Inheritor2), - toSingletonUINT(0) - ); + v1dmsFacet.allocateERC721Tokens(address(erc721t), toSingletonAdd(vault1Inheritor2), toSingletonUINT(0)); + v1dmsFacet.allocateERC721Tokens(address(erc721t), toSingletonAdd(vault1Inheritor2), toSingletonUINT(0)); // //confirm storage - DMSFacet.AllocatedERC721Tokens[] - memory vault1Inheritor2Alloc = v1dmsFacet.getAllocatedERC721Tokens( - vault1Inheritor2 - ); + DMSFacet.AllocatedERC721Tokens[] memory vault1Inheritor2Alloc = + v1dmsFacet.getAllocatedERC721Tokens(vault1Inheritor2); assertEq(vault1Inheritor2Alloc[0].token, address(erc721t)); assertEq(vault1Inheritor2Alloc[0].tokenIDs[0], 0); // //make sure token is unallocated from previous inheritor - vault1Inheritor1Alloc = v1dmsFacet.getAllocatedERC721Tokens( - vault1Inheritor1 - ); + vault1Inheritor1Alloc = v1dmsFacet.getAllocatedERC721Tokens(vault1Inheritor1); assertEq(vault1Inheritor1Alloc.length, 0); // //unallocate and withdraw - v1dmsFacet.allocateERC721Tokens( - address(erc721t), - toSingletonAdd(address(0)), - toSingletonUINT(0) - ); - assertEq( - v1dmsFacet - .getAllocatedERC721TokenIds(vault1Inheritor2, address(erc721t)) - .length, - 0 - ); + v1dmsFacet.allocateERC721Tokens(address(erc721t), toSingletonAdd(address(0)), toSingletonUINT(0)); + assertEq(v1dmsFacet.getAllocatedERC721TokenIds(vault1Inheritor2, address(erc721t)).length, 0); // //withdraw the token v1ERC721Facet.withdrawERC721Token(address(erc721t), 0, vault1Owner); // //confirm ownership @@ -121,23 +86,15 @@ contract ERC721FacetTest is DDeployments { // //cannot allocate to non existent inheritor vm.expectRevert((LibDMS.NotInheritor.selector)); - v1dmsFacet.allocateERC721Tokens( - address(erc721t2), - toSingletonAdd(mkaddr("noninheritor")), - toSingletonUINT(1) - ); + v1dmsFacet.allocateERC721Tokens(address(erc721t2), toSingletonAdd(mkaddr("noninheritor")), toSingletonUINT(1)); // //mass allocate tokens v1dmsFacet.allocateERC721Tokens( - address(erc721t2), - toTriAddress(vault1Inheritor2, vault1Inheritor2, vault1Inheritor2), - toTriUINT(0, 1, 2) + address(erc721t2), toTriAddress(vault1Inheritor2, vault1Inheritor2, vault1Inheritor2), toTriUINT(0, 1, 2) ); // //double check storage - vault1Inheritor2Alloc = v1dmsFacet.getAllocatedERC721Tokens( - vault1Inheritor2 - ); + vault1Inheritor2Alloc = v1dmsFacet.getAllocatedERC721Tokens(vault1Inheritor2); assertEq(vault1Inheritor2Alloc[0].tokenIDs.length, 3); } } diff --git a/test/EtherOpsTests.t.sol b/test/EtherOpsTests.t.sol index 1b265d8..8230fe0 100644 --- a/test/EtherOpsTests.t.sol +++ b/test/EtherOpsTests.t.sol @@ -16,15 +16,10 @@ contract EtherOpsTests is DDeployments { // get ether allocation data for all inheritors // only one inheritor currently present - DMSFacet.AllInheritorEtherAllocs[] - memory eAllocs = new DMSFacet.AllInheritorEtherAllocs[](1); - eAllocs[0] = DMSFacet.AllInheritorEtherAllocs({ - inheritor: vault1Inheritor1, - weiAlloc: 10000 - }); + DMSFacet.AllInheritorEtherAllocs[] memory eAllocs = new DMSFacet.AllInheritorEtherAllocs[](1); + eAllocs[0] = DMSFacet.AllInheritorEtherAllocs({inheritor: vault1Inheritor1, weiAlloc: 10000}); //get data onchain - DMSFacet.AllInheritorEtherAllocs[] memory onchainAllocs = v1dmsFacet - .allEtherAllocations(); + DMSFacet.AllInheritorEtherAllocs[] memory onchainAllocs = v1dmsFacet.allEtherAllocations(); assertEq(onchainAllocs[0].inheritor, eAllocs[0].inheritor); assertEq(onchainAllocs[0].weiAlloc, eAllocs[0].weiAlloc); @@ -37,25 +32,12 @@ contract EtherOpsTests is DDeployments { uint256 v1Inheritor2eAlloc = freeEther - 10000000; //try to allocate more thn available ether - vm.expectRevert( - abi.encodeWithSelector( - LibDMS.EtherAllocationOverflow.selector, - 2 ether - freeEther - ) - ); - v1dmsFacet.addInheritors( - toSingletonAdd(vault1Inheritor2), - toSingletonUINT(2 ether) - ); + vm.expectRevert(abi.encodeWithSelector(LibDMS.EtherAllocationOverflow.selector, 2 ether - freeEther)); + v1dmsFacet.addInheritors(toSingletonAdd(vault1Inheritor2), toSingletonUINT(2 ether)); //allocate normally - v1dmsFacet.addInheritors( - toSingletonAdd(vault1Inheritor2), - toSingletonUINT(v1Inheritor2eAlloc) - ); - uint256 v1Inheritor2EtherAlloc = v1dmsFacet.inheritorEtherAllocation( - vault1Inheritor2 - ); + v1dmsFacet.addInheritors(toSingletonAdd(vault1Inheritor2), toSingletonUINT(v1Inheritor2eAlloc)); + uint256 v1Inheritor2EtherAlloc = v1dmsFacet.inheritorEtherAllocation(vault1Inheritor2); assertEq(v1Inheritor2EtherAlloc, freeEther - 10000000); //try to withdraw more than available @@ -66,8 +48,7 @@ contract EtherOpsTests is DDeployments { //unallocate from both inheritors //ORDER matters(not really anymore) v1dmsFacet.allocateEther( - toDualAdd(vault1Inheritor2, vault1Inheritor1), - toDualUINT(v1Inheritor2eAlloc - 500, 10000 - 500) + toDualAdd(vault1Inheritor2, vault1Inheritor1), toDualUINT(v1Inheritor2eAlloc - 500, 10000 - 500) ); v1EtherFacet.withdrawEther(freeEther + 1000, vault1Owner); diff --git a/test/MockERC1155.sol b/test/MockERC1155.sol index ee15922..322edb9 100644 --- a/test/MockERC1155.sol +++ b/test/MockERC1155.sol @@ -1,9 +1,9 @@ pragma solidity 0.8.4; -import "solmate.git/tokens/ERC1155.sol"; -contract VaultERC1155Token is ERC1155{ +import "solmate.git/tokens/ERC1155.sol"; - function mint(address _to,uint256 _id,uint256 _amount) public{ - _mint(_to,_id,_amount,""); +contract VaultERC1155Token is ERC1155 { + function mint(address _to, uint256 _id, uint256 _amount) public { + _mint(_to, _id, _amount, ""); } -} \ No newline at end of file +} diff --git a/test/MockERC20.sol b/test/MockERC20.sol index 3411afc..f7ca00b 100644 --- a/test/MockERC20.sol +++ b/test/MockERC20.sol @@ -2,10 +2,8 @@ pragma solidity 0.8.4; import "solmate.git/tokens/ERC20.sol"; -contract VaultERC20Token is ERC20("VAULTTOKEN", "VLT",18) { - - - function mint(address _to,uint256 _amount) public{ - _mint(_to,_amount); +contract VaultERC20Token is ERC20("VAULTTOKEN", "VLT", 18) { + function mint(address _to, uint256 _amount) public { + _mint(_to, _amount); } } diff --git a/test/MockERC721.sol b/test/MockERC721.sol index 4901cb4..57e832d 100644 --- a/test/MockERC721.sol +++ b/test/MockERC721.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.4; import "solmate.git/tokens/ERC721.sol"; contract VaultERC721Token is ERC721("VAULTNFT", "VNFT") { - function mint(address _to,uint256 _id) public{ - _mint(_to,_id); + function mint(address _to, uint256 _id) public { + _mint(_to, _id); } }