Have the assurance to interact with 100% genuine SmartContracts;
Easily Smart Contract code update;
Easy search system of similar Smart Contract through events
We usually use a Model - Factory pattern to fuse flexibility and security together.
The Model always contains all the Business Logic of the Smart Contract. It does not have a constructor, but an optional initialization method.
The Factory has the logic to reference the original model and to clone it keeping track of all the instances through events. The initialization method is general purpose in order to make the model updateable.
pragma solidity ^0.7.0;pragma abicoder v2;contract Model { address public factory;functioninit() {require(factory ==address(0),"Init already called!");//This links the Model directly to the Factory factory =msg.sender;/* * Other init stuff */ }}pragma solidity ^0.7.0;pragma abicoder v2;contract Factory { address public model; address public doubleProxy; event ModelDeployed(address indexed instanceAddress, address indexed sender, bytes initResultData);constructor(address _doubleProxy, address _model) { doubleProxy = _doubleProxy; model = _model; }functionsetDoubleProxy(address _doubleProxy) publicbyDFO { doubleProxy = _doubleProxy; }//Model can be changed only by authorization (Proposal)functionsetModel(address _model) publicbyDFO { model = _model; }//Clones the bytecode of the Model and calls the model initialization method.//In order to maintain the Factory totally model independant, initialization data must be passed as ABI-Encoded parameters//E.G. in this case, data is equal to bytes4(keccak256("init()")), which corresponds to the init() method of the actual Model.//This method will work even if the Model and its initialization method changesfunctiondeploy(bytes memory data) publicreturns (address contractAddress, bytes memory initResultData) { initResultData =_call(contractAddress =_clone(model), data); emit ModelDeployed(contractAddress,msg.sender, initResultData); }function_clone(address original) privatereturns (address copy) { assembly {mstore(0,or(0x5880730000000000000000000000000000000000000000803b80938091923cF3,mul(original,0x1000000000000000000) ) ) copy :=create(0,0,32)switchextcodesize(copy)case0 {invalid() } } }function_call(address location, bytes memory payload) privatereturns(bytes memory returnData) { assembly {let result := call(gas(),location,0,add(payload, 0x20),mload(payload),0,0)let size := returndatasize() returnData :=mload(0x40)mstore(returnData, size)let returnDataPayloadStart := add(returnData, 0x20)returndatacopy(returnDataPayloadStart,0, size)mstore(0x40,add(returnDataPayloadStart, size))switch result case0 {revert(returnDataPayloadStart, size)} } } modifier byDFO() {require(IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(msg.sender),"Unauthorized."); _; }}
Below are some use cases of Factory contracts developed and used by Ethos: