├── .gitignore ├── Dockerfile ├── contracts ├── WUSD │ ├── AllowedAMM.sol │ ├── IWUSDExtension.sol │ ├── IWUSDExtensionController.sol │ ├── IWUSDNoteController.sol │ ├── WUSDExtension.sol │ ├── WUSDExtensionController.sol │ ├── WUSDFarmingRegularExtension.sol │ ├── WUSDNoteController.sol │ └── util │ │ ├── DFOHub.sol │ │ ├── ERC1155Receiver.sol │ │ ├── IERC1155.sol │ │ ├── IERC20.sol │ │ ├── IERC20WrapperV1.sol │ │ ├── IEthItem.sol │ │ ├── IEthItemInteroperableInterface.sol │ │ ├── IEthItemOrchestrator.sol │ │ └── INativeV1.sol ├── amm-aggregator │ ├── aggregator │ │ ├── AMMAggregator.sol │ │ └── IAMMAggregator.sol │ ├── common │ │ ├── AMM.sol │ │ ├── AMMData.sol │ │ └── IAMM.sol │ ├── models │ │ ├── Balancer │ │ │ └── 1 │ │ │ │ ├── BalancerAMMV1.sol │ │ │ │ └── IBalancerAMMV1.sol │ │ ├── Mooniswap │ │ │ └── 1 │ │ │ │ ├── IMooniswapAMMV1.sol │ │ │ │ └── MooniswapAMMV1.sol │ │ ├── SushiSwap │ │ │ └── 1 │ │ │ │ ├── ISushiSwapAMMV1.sol │ │ │ │ └── SushiSwapAMMV1.sol │ │ ├── UniswapV2 │ │ │ └── 1 │ │ │ │ ├── IUniswapV2AMMV1.sol │ │ │ │ └── UniswapV2AMMV1.sol │ │ └── UniswapV3 │ │ │ └── 1 │ │ │ ├── IUniswapV3AMMV1.sol │ │ │ └── UniswapV3AMMV1.sol │ └── util │ │ ├── ERC165.sol │ │ ├── IERC165.sol │ │ └── IERC20.sol ├── farming │ ├── FarmData.sol │ ├── FarmDataGen1.sol │ ├── FarmDataRegular.sol │ ├── FarmExtension.sol │ ├── FarmExtensionGen1.sol │ ├── FarmFactory.sol │ ├── FarmMain.sol │ ├── FarmMainGen1.sol │ ├── FarmMainGen1V2.sol │ ├── FarmMainMinStake.sol │ ├── FarmMainRegular.sol │ ├── FarmMainRegularMinStake.sol │ ├── IFarmExtension.sol │ ├── IFarmExtensionGen1.sol │ ├── IFarmExtensionRegular.sol │ ├── IFarmFactory.sol │ ├── IFarmMain.sol │ ├── IFarmMainGen1.sol │ ├── IFarmMainRegular.sol │ ├── dfo │ │ ├── DFOBasedFarmExtension.sol │ │ ├── DFOBasedFarmExtensionFactory.sol │ │ ├── DFOBasedFarmExtensionGen1.sol │ │ └── ManageFarmingFunctionality.sol │ └── util │ │ ├── DFOHub.sol │ │ ├── ERC1155Receiver.sol │ │ ├── IERC1155.sol │ │ ├── IERC165.sol │ │ ├── IERC20.sol │ │ ├── IERC20Mintable.sol │ │ ├── IEthItem.sol │ │ ├── IEthItemInteroperableInterface.sol │ │ ├── IEthItemOrchestrator.sol │ │ └── INativeV1.sol ├── fixed-inflation │ ├── FixedInflation.sol │ ├── FixedInflationData.sol │ ├── FixedInflationExtension.sol │ ├── FixedInflationFactory.sol │ ├── FixedInflationUniV3.sol │ ├── IFixedInflation.sol │ ├── IFixedInflationExtension.sol │ ├── IFixedInflationFactory.sol │ ├── dfo │ │ ├── DFOBasedFixedInflationExtension.sol │ │ ├── DFOBasedFixedInflationExtensionFactory.sol │ │ └── ManageFixedInflationFunctionality.sol │ └── util │ │ ├── DFOHub.sol │ │ ├── IERC20.sol │ │ ├── IERC20Burnable.sol │ │ └── IERC20Mintable.sol ├── index │ ├── IIndex.sol │ ├── Index.sol │ └── util │ │ ├── DFOHub.sol │ │ ├── ERC1155Receiver.sol │ │ ├── IERC1155.sol │ │ ├── IERC20.sol │ │ ├── IERC20WrapperV1.sol │ │ ├── IEthItem.sol │ │ ├── IEthItemInteroperableInterface.sol │ │ ├── IEthItemOrchestrator.sol │ │ └── INativeV1.sol ├── presto │ ├── IPresto.sol │ ├── IPrestoUniV3.sol │ ├── Presto.sol │ ├── PrestoData.sol │ ├── PrestoDataUniV3.sol │ ├── PrestoUniV3.sol │ ├── util │ │ ├── DFOHub.sol │ │ ├── ERC1155Receiver.sol │ │ ├── IERC1155.sol │ │ ├── IERC20.sol │ │ ├── IERC20Burnable.sol │ │ ├── IEthItem.sol │ │ ├── IEthItemInteroperableInterface.sol │ │ └── INativeV1.sol │ └── verticalizations │ │ ├── FarmingPresto.sol │ │ ├── IndexPresto.sol │ │ └── WUSDPresto.sol └── util │ └── uniswapV3 │ ├── IMulticall.sol │ ├── INonfungiblePositionManager.sol │ ├── IPeripheryImmutableState.sol │ ├── IPeripheryPayments.sol │ ├── IPoolInitializer.sol │ ├── IQuoter.sol │ ├── IQuoterV2.sol │ ├── ISwapRouter.sol │ ├── ITickLens.sol │ ├── IUniswapV3Factory.sol │ ├── IUniswapV3MintCallback.sol │ ├── IUniswapV3Pool.sol │ ├── IUniswapV3PoolActions.sol │ ├── PoolAddress.sol │ └── TickMath.sol ├── old_test ├── WUSD.js ├── WUSDFarm.js ├── amm.js ├── disableOldSetup.js ├── farming.js ├── farmingGen1.js ├── farmingPresto.js ├── farming_min_stake.js ├── fixedInflation-v3.js ├── fixedInflation.js ├── index.js ├── liquidityMining.js ├── multipleProposal.js ├── presto.js └── transferFix.js ├── package.json ├── procedures ├── farming_gen_1 │ └── index.js ├── farming_gen_2 │ └── index.js ├── misc.js └── routines │ └── index.js ├── resources ├── OS │ ├── OSFarmingExtension.sol │ ├── OSRoutinesExtension.sol │ ├── buildOsStuff.js │ └── contracts.json └── knowledgeBase │ ├── 1.json │ ├── 10.json │ ├── 4.json │ └── 5.json └── test └── multiverse-procedures.js /.gitignore: -------------------------------------------------------------------------------- 1 | /**/build 2 | /**/package-lock.json 3 | /**/yarn.lock 4 | /**/node_modules 5 | /**/lib 6 | /**/.vscode 7 | /**/artifacts 8 | /**/bin 9 | /**/out 10 | /**/flat 11 | /**/.env 12 | /**/*.env 13 | /**/tmp 14 | /**/dump 15 | /**/data 16 | truffle-config.js 17 | .todo 18 | yarn-error.log -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:latest 2 | 3 | RUN mkdir -p /usr/local/ethaffairs 4 | 5 | COPY . /usr/local/ethaffairs/ 6 | 7 | WORKDIR /usr/local/ethaffairs 8 | 9 | RUN npm install 10 | 11 | ENTRYPOINT npm run test -------------------------------------------------------------------------------- /contracts/WUSD/AllowedAMM.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | struct AllowedAMM { 6 | address ammAddress; 7 | address[] liquidityPools; 8 | } -------------------------------------------------------------------------------- /contracts/WUSD/IWUSDExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IWUSDExtension { 6 | 7 | function controller() external view returns(address); 8 | } -------------------------------------------------------------------------------- /contracts/WUSD/IWUSDExtensionController.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | pragma abicoder v2; 5 | 6 | import "./AllowedAMM.sol"; 7 | 8 | interface IWUSDExtensionController { 9 | 10 | function rebalanceByCreditBlockInterval() external view returns(uint256); 11 | 12 | function lastRebalanceByCreditBlock() external view returns(uint256); 13 | 14 | function wusdInfo() external view returns (address, uint256, address); 15 | 16 | function allowedAMMs() external view returns(AllowedAMM[] memory); 17 | 18 | function extension() external view returns (address); 19 | 20 | function addLiquidity( 21 | uint256 ammPosition, 22 | uint256 liquidityPoolPosition, 23 | uint256 liquidityPoolAmount, 24 | bool byLiquidityPool 25 | ) external returns(uint256); 26 | } -------------------------------------------------------------------------------- /contracts/WUSD/IWUSDNoteController.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./util/INativeV1.sol"; 6 | 7 | interface IWUSDNoteController { 8 | 9 | function wusdCollection() external view returns(address); 10 | function wusdObjectId() external view returns(uint256); 11 | function wusdNoteObjectId() external view returns(uint256); 12 | function multiplier() external view returns(uint256); 13 | 14 | function info() external view returns(address, uint256, uint256, uint256); 15 | 16 | function init(address _wusdCollection, uint256 _wusdObjectId, uint256 _wusdNoteObjectId, uint256 _multiplier) external; 17 | } -------------------------------------------------------------------------------- /contracts/WUSD/WUSDExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | pragma abicoder v2; 5 | 6 | import "./util/IEthItemOrchestrator.sol"; 7 | import "./util/INativeV1.sol"; 8 | import "./util/IERC20.sol"; 9 | import "../amm-aggregator/common/IAMM.sol"; 10 | import "./AllowedAMM.sol"; 11 | import "./IWUSDExtension.sol"; 12 | 13 | contract WUSDExtension is IWUSDExtension { 14 | 15 | uint256 private constant DECIMALS = 18; 16 | 17 | address private _controller; 18 | 19 | address private _collection; 20 | 21 | uint256 private _mainItemObjectId; 22 | address private _mainItemInteroperableAddress; 23 | 24 | constructor(address orchestrator) { 25 | _controller = msg.sender; 26 | (_collection,) = IEthItemOrchestrator(orchestrator).createNative(abi.encodeWithSignature("init(string,string,bool,string,address,bytes)", "Covenants Wrapped USD", "WUSD", true, "ipfs://ipfs/QmbFb9QdwSV1i8F1FhvBoL7XuCU7D1wRTLRRi23Zvu8Z9J", address(this), ""), ""); 27 | (_mainItemObjectId, _mainItemInteroperableAddress) = _mintEmpty("Wrapped USD", "WUSD", "ipfs://ipfs/QmTj9k7vq8DqLFuS3TrGGNDaacHL2cTgLjJ6Tu8ZbKwTHm", true); 28 | } 29 | 30 | function collection() public view returns (address) { 31 | return _collection; 32 | } 33 | 34 | function data() public view returns (address, uint256, address) { 35 | return (_collection, _mainItemObjectId, _mainItemInteroperableAddress); 36 | } 37 | 38 | function controller() public override view returns (address) { 39 | return _controller; 40 | } 41 | 42 | modifier controllerOnly() { 43 | require(msg.sender == _controller, "Unauthorized action"); 44 | _; 45 | } 46 | 47 | function mintEmpty(string memory tokenName, string memory tokenSymbol, string memory objectUri, bool editable) public controllerOnly returns(uint256 objectId, address interoperableInterfaceAddress) { 48 | return _mintEmpty(tokenName, tokenSymbol, objectUri, editable); 49 | } 50 | 51 | function _mintEmpty(string memory tokenName, string memory tokenSymbol, string memory objectUri, bool editable) private returns(uint256 objectId, address interoperableInterfaceAddress) { 52 | INativeV1 theCollection = INativeV1(_collection); 53 | (objectId, interoperableInterfaceAddress) = theCollection.mint(10**18, tokenName, tokenSymbol, objectUri, editable); 54 | theCollection.burn(objectId, theCollection.balanceOf(address(this), objectId)); 55 | } 56 | 57 | function setCollectionUri(string memory uri) public controllerOnly { 58 | INativeV1(_collection).setUri(uri); 59 | } 60 | 61 | function setItemUri(uint256 existingObjectId, string memory uri) public controllerOnly { 62 | INativeV1(_collection).setUri(existingObjectId, uri); 63 | } 64 | 65 | function makeReadOnly(uint256 objectId) public controllerOnly { 66 | INativeV1(_collection).makeReadOnly(objectId); 67 | } 68 | 69 | function mintFor(address ammPlugin, address liquidityPoolAddress, uint256 liquidityPoolAmount, address receiver) public controllerOnly { 70 | _safeTransferFrom(liquidityPoolAddress, msg.sender, address(this), liquidityPoolAmount); 71 | _mint(_mainItemObjectId, _normalizeAndSumAmounts(ammPlugin, liquidityPoolAddress, liquidityPoolAmount), receiver); 72 | } 73 | 74 | function mintForRebalanceByCredit(AllowedAMM[] memory amms) public controllerOnly returns(uint256 credit) { 75 | uint256 totalSupply = INativeV1(_collection).totalSupply(_mainItemObjectId); 76 | for(uint256 i = 0; i < amms.length; i++) { 77 | for(uint256 j = 0; j < amms[i].liquidityPools.length; j++) { 78 | credit += _normalizeAndSumAmounts(amms[i].ammAddress, amms[i].liquidityPools[j], IERC20(amms[i].liquidityPools[j]).balanceOf(address(this))); 79 | } 80 | } 81 | require(credit > totalSupply, "No credit"); 82 | _mint(_mainItemObjectId, credit = (credit - totalSupply), msg.sender); 83 | } 84 | 85 | function burnFor(uint256 objectId, uint256 value, address receiver) public controllerOnly { 86 | _safeTransferFrom(_mainItemInteroperableAddress, msg.sender, address(this), INativeV1(_collection).toInteroperableInterfaceAmount(_mainItemObjectId, value)); 87 | INativeV1(_collection).burn(_mainItemObjectId, value); 88 | _mint(objectId, value, receiver); 89 | } 90 | 91 | function _mint(uint256 objectId, uint256 amount, address receiver) private { 92 | INativeV1(_collection).mint(objectId, amount); 93 | INativeV1(_collection).safeTransferFrom(address(this), receiver, objectId, INativeV1(_collection).balanceOf(address(this), objectId), ""); 94 | } 95 | 96 | function burnFor(address from, uint256 value, address ammPlugin, address liquidityPoolAddress, uint256 liquidityPoolAmount, address liquidityPoolReceiver) public controllerOnly { 97 | _safeTransferFrom(_mainItemInteroperableAddress, msg.sender, address(this), INativeV1(_collection).toInteroperableInterfaceAmount(_mainItemObjectId, value)); 98 | uint256 toBurn = _normalizeAndSumAmounts(ammPlugin, liquidityPoolAddress, liquidityPoolAmount); 99 | require(value >= toBurn, "Insufficient Amount"); 100 | if(value > toBurn) { 101 | INativeV1(_collection).safeTransferFrom(address(this), from, _mainItemObjectId, value - toBurn, ""); 102 | } 103 | INativeV1(_collection).burn(_mainItemObjectId, toBurn); 104 | _safeTransfer(liquidityPoolAddress, liquidityPoolReceiver, liquidityPoolAmount); 105 | } 106 | 107 | function _safeTransfer(address erc20TokenAddress, address to, uint256 value) internal { 108 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); 109 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); 110 | } 111 | 112 | function _safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) private { 113 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); 114 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); 115 | } 116 | 117 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 118 | assembly { 119 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 120 | let size := returndatasize() 121 | returnData := mload(0x40) 122 | mstore(returnData, size) 123 | let returnDataPayloadStart := add(returnData, 0x20) 124 | returndatacopy(returnDataPayloadStart, 0, size) 125 | mstore(0x40, add(returnDataPayloadStart, size)) 126 | switch result case 0 {revert(returnDataPayloadStart, size)} 127 | } 128 | } 129 | 130 | function _normalizeAndSumAmounts(address ammPlugin, address liquidityPoolAddress, uint256 liquidityPoolAmount) 131 | private 132 | view 133 | returns(uint256 amount) { 134 | IERC20 liquidityPool = IERC20(liquidityPoolAddress); 135 | (uint256[] memory amounts, address[] memory tokens) = IAMM(ammPlugin).byLiquidityPoolAmount(address(liquidityPool), liquidityPoolAmount); 136 | for(uint256 i = 0; i < amounts.length; i++) { 137 | amount += _normalizeTokenAmountToDefaultDecimals(tokens[i], amounts[i]); 138 | } 139 | } 140 | 141 | function _normalizeTokenAmountToDefaultDecimals(address tokenAddress, uint256 amount) internal virtual view returns(uint256) { 142 | uint256 remainingDecimals = DECIMALS; 143 | IERC20 token = IERC20(tokenAddress); 144 | remainingDecimals -= token.decimals(); 145 | 146 | if(remainingDecimals == 0) { 147 | return amount; 148 | } 149 | 150 | return amount * (remainingDecimals == 0 ? 1 : (10**remainingDecimals)); 151 | } 152 | } -------------------------------------------------------------------------------- /contracts/WUSD/WUSDNoteController.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./util/ERC1155Receiver.sol"; 6 | import "./util/INativeV1.sol"; 7 | import "./IWUSDNoteController.sol"; 8 | 9 | contract WUSDNoteController is IWUSDNoteController, ERC1155Receiver { 10 | 11 | address public override wusdCollection; 12 | uint256 public override wusdObjectId; 13 | uint256 public override wusdNoteObjectId; 14 | uint256 public override multiplier; 15 | 16 | function init(address _wusdCollection, uint256 _wusdObjectId, uint256 _wusdNoteObjectId, uint256 _multiplier) public override { 17 | require(wusdCollection == address(0), "Already init"); 18 | wusdCollection = _wusdCollection; 19 | wusdObjectId = _wusdObjectId; 20 | wusdNoteObjectId = _wusdNoteObjectId; 21 | multiplier = _multiplier; 22 | } 23 | 24 | function info() public override view returns(address, uint256, uint256, uint256) { 25 | return (wusdCollection, wusdObjectId, wusdNoteObjectId, multiplier); 26 | } 27 | 28 | function onERC1155BatchReceived( 29 | address, 30 | address from, 31 | uint256[] memory ids, 32 | uint256[] memory values, 33 | bytes memory data 34 | ) 35 | public 36 | override 37 | returns(bytes4) { 38 | require(msg.sender == wusdCollection, "Only WUSD collection allowed here"); 39 | uint256[] memory usdIds = new uint256[](ids.length); 40 | uint256[] memory usdValues = new uint256[](ids.length); 41 | for(uint256 i = 0; i < ids.length; i++) { 42 | require(ids[i] == wusdNoteObjectId, "Only WUSD Note allowed here"); 43 | usdIds[i] = wusdObjectId; 44 | usdValues[i] = values[i] * multiplier; 45 | } 46 | INativeV1 collection = INativeV1(wusdCollection); 47 | collection.burnBatch(ids, values); 48 | collection.safeBatchTransferFrom(address(this), from, usdIds, usdValues, data); 49 | return this.onERC1155BatchReceived.selector; 50 | } 51 | 52 | function onERC1155Received( 53 | address, 54 | address from, 55 | uint256 id, 56 | uint256 value, 57 | bytes calldata data 58 | ) 59 | public 60 | override 61 | returns(bytes4) { 62 | require(msg.sender == wusdCollection, "Only WUSD collection allowed here"); 63 | require(id == wusdNoteObjectId, "Only WUSD Note allowed here"); 64 | INativeV1 collection = INativeV1(wusdCollection); 65 | collection.burn(id, value); 66 | collection.safeTransferFrom(address(this), from, wusdObjectId, value * multiplier, data); 67 | return this.onERC1155Received.selector; 68 | } 69 | } -------------------------------------------------------------------------------- /contracts/WUSD/util/DFOHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IDoubleProxy { 6 | function proxy() external view returns (address); 7 | } 8 | 9 | interface IMVDProxy { 10 | function getMVDFunctionalitiesManagerAddress() external view returns(address); 11 | function getMVDWalletAddress() external view returns (address); 12 | function getStateHolderAddress() external view returns(address); 13 | function submit(string calldata codeName, bytes calldata data) external payable returns(bytes memory returnData); 14 | } 15 | 16 | interface IMVDFunctionalitiesManager { 17 | function isAuthorizedFunctionality(address functionality) external view returns(bool); 18 | } 19 | 20 | interface IStateHolder { 21 | function getUint256(string calldata name) external view returns(uint256); 22 | function getAddress(string calldata name) external view returns(address); 23 | function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal); 24 | } -------------------------------------------------------------------------------- /contracts/WUSD/util/ERC1155Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | abstract contract ERC1155Receiver { 6 | bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; 7 | 8 | mapping(bytes4 => bool) private _supportedInterfaces; 9 | 10 | constructor() { 11 | _registerInterface(_INTERFACE_ID_ERC165); 12 | _registerInterface( 13 | ERC1155Receiver(0).onERC1155Received.selector ^ 14 | ERC1155Receiver(0).onERC1155BatchReceived.selector 15 | ); 16 | } 17 | 18 | function supportsInterface(bytes4 interfaceId) public view returns (bool) { 19 | return _supportedInterfaces[interfaceId]; 20 | } 21 | 22 | function _registerInterface(bytes4 interfaceId) internal virtual { 23 | require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); 24 | _supportedInterfaces[interfaceId] = true; 25 | } 26 | 27 | function onERC1155Received( 28 | address operator, 29 | address from, 30 | uint256 id, 31 | uint256 value, 32 | bytes calldata data 33 | ) 34 | external 35 | virtual 36 | returns(bytes4); 37 | 38 | function onERC1155BatchReceived( 39 | address operator, 40 | address from, 41 | uint256[] calldata ids, 42 | uint256[] calldata values, 43 | bytes calldata data 44 | ) 45 | external 46 | virtual 47 | returns(bytes4); 48 | } 49 | -------------------------------------------------------------------------------- /contracts/WUSD/util/IERC1155.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC1155 { 6 | 7 | event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); 8 | 9 | event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); 10 | 11 | event ApprovalForAll(address indexed account, address indexed operator, bool approved); 12 | 13 | event URI(string value, uint256 indexed id); 14 | 15 | function balanceOf(address account, uint256 id) external view returns (uint256); 16 | 17 | function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); 18 | 19 | function setApprovalForAll(address operator, bool approved) external; 20 | 21 | function isApprovedForAll(address account, address operator) external view returns (bool); 22 | 23 | function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; 24 | 25 | function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/WUSD/util/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC20 { 6 | 7 | function totalSupply() external view returns (uint256); 8 | 9 | function balanceOf(address account) external view returns (uint256); 10 | 11 | function transfer(address recipient, uint256 amount) external returns (bool); 12 | 13 | function allowance(address owner, address spender) external view returns (uint256); 14 | 15 | function approve(address spender, uint256 amount) external returns (bool); 16 | 17 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 18 | 19 | function decimals() external view returns (uint8); 20 | } 21 | -------------------------------------------------------------------------------- /contracts/WUSD/util/IERC20WrapperV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IEthItem.sol"; 6 | 7 | interface IERC20WrapperV1 is IEthItem { 8 | 9 | function source(uint256 objectId) external view returns (address erc20TokenAddress); 10 | 11 | function object(address erc20TokenAddress) external view returns (uint256 objectId); 12 | 13 | function mint(address erc20TokenAddress, uint256 amount) external returns (uint256 objectId, address wrapperAddress); 14 | 15 | function mintETH() external payable returns (uint256 objectId, address wrapperAddress); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/WUSD/util/IEthItem.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IERC1155.sol"; 6 | import "./IEthItemInteroperableInterface.sol"; 7 | 8 | interface IEthItem is IERC1155 { 9 | 10 | function name() external view returns (string memory); 11 | 12 | function symbol() external view returns (string memory); 13 | 14 | function totalSupply(uint256 objectId) external view returns (uint256); 15 | 16 | function name(uint256 objectId) external view returns (string memory); 17 | 18 | function symbol(uint256 objectId) external view returns (string memory); 19 | 20 | function decimals(uint256 objectId) external view returns (uint256); 21 | 22 | function uri(uint256 objectId) external view returns (string memory); 23 | 24 | function mainInterfaceVersion() external pure returns(uint256 ethItemInteroperableVersion); 25 | 26 | function toInteroperableInterfaceAmount(uint256 objectId, uint256 ethItemAmount) external view returns (uint256 interoperableInterfaceAmount); 27 | 28 | function toMainInterfaceAmount(uint256 objectId, uint256 erc20WrapperAmount) external view returns (uint256 mainInterfaceAmount); 29 | 30 | function interoperableInterfaceModel() external view returns (address, uint256); 31 | 32 | function asInteroperable(uint256 objectId) external view returns (IEthItemInteroperableInterface); 33 | 34 | function emitTransferSingleEvent(address sender, address from, address to, uint256 objectId, uint256 amount) external; 35 | 36 | function mint(uint256 amount, string calldata partialUri) 37 | external 38 | returns (uint256, address); 39 | 40 | function burn( 41 | uint256 objectId, 42 | uint256 amount 43 | ) external; 44 | 45 | function burnBatch( 46 | uint256[] calldata objectIds, 47 | uint256[] calldata amounts 48 | ) external; 49 | } -------------------------------------------------------------------------------- /contracts/WUSD/util/IEthItemInteroperableInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IERC20.sol"; 6 | 7 | interface IEthItemInteroperableInterface is IERC20 { 8 | 9 | function mainInterface() external view returns (address); 10 | 11 | function objectId() external view returns (uint256); 12 | 13 | function mint(address owner, uint256 amount) external; 14 | 15 | function burn(address owner, uint256 amount) external; 16 | 17 | function permitNonce(address sender) external view returns(uint256); 18 | 19 | function permit(address owner, address spender, uint value, uint8 v, bytes32 r, bytes32 s) external; 20 | 21 | function interoperableInterfaceVersion() external pure returns(uint256 ethItemInteroperableInterfaceVersion); 22 | } -------------------------------------------------------------------------------- /contracts/WUSD/util/IEthItemOrchestrator.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IEthItemOrchestrator { 6 | function createNative(bytes calldata modelInitPayload, string calldata ens) 7 | external 8 | returns (address newNativeAddress, bytes memory modelInitCallResponse); 9 | } -------------------------------------------------------------------------------- /contracts/WUSD/util/INativeV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IEthItem.sol"; 6 | 7 | interface INativeV1 is IEthItem { 8 | 9 | function init(string calldata name, string calldata symbol, bool hasDecimals, string calldata collectionUri, address extensionAddress, bytes calldata extensionInitPayload) external returns(bytes memory extensionInitCallResponse); 10 | 11 | function extension() external view returns (address extensionAddress); 12 | 13 | function canMint(address operator) external view returns (bool result); 14 | 15 | function isEditable(uint256 objectId) external view returns (bool result); 16 | 17 | function releaseExtension() external; 18 | 19 | function uri() external view returns (string memory); 20 | 21 | function decimals() external view returns (uint256); 22 | 23 | function mint(uint256 amount, string calldata tokenName, string calldata tokenSymbol, string calldata objectUri, bool editable) external returns (uint256 objectId, address tokenAddress); 24 | 25 | function mint(uint256 amount, string calldata tokenName, string calldata tokenSymbol, string calldata objectUri) external returns (uint256 objectId, address tokenAddress); 26 | 27 | function mint(uint256 objectId, uint256 amount) external; 28 | 29 | function makeReadOnly(uint256 objectId) external; 30 | 31 | function setUri(string calldata newUri) external; 32 | 33 | function setUri(uint256 objectId, string calldata newUri) external; 34 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/aggregator/AMMAggregator.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./IAMMAggregator.sol"; 6 | 7 | contract AMMAggregator is IAMMAggregator { 8 | 9 | address public override host; 10 | 11 | uint256 private _ammsLength; 12 | mapping(uint256 => address) private _amms; 13 | 14 | constructor(address _host, address[] memory ammsToAdd) { 15 | host = _host; 16 | for(uint256 i = 0; i < ammsToAdd.length; i++) { 17 | IAMM amm = IAMM(_amms[_ammsLength++] = ammsToAdd[i]); 18 | (string memory name, uint256 version) = amm.info(); 19 | emit AMM(ammsToAdd[i], name, version); 20 | } 21 | } 22 | 23 | modifier authorizedOnly virtual { 24 | require(msg.sender == host, "Unauthorized action"); 25 | _; 26 | } 27 | 28 | function setHost(address newHost) public override authorizedOnly { 29 | host = newHost; 30 | } 31 | 32 | function amms() public override view returns (address[] memory returnData) { 33 | returnData = new address[](_ammsLength); 34 | for(uint256 i = 0 ; i < _ammsLength; i++) { 35 | returnData[i] = _amms[i]; 36 | } 37 | } 38 | 39 | function remove(uint256 index) public override authorizedOnly { 40 | require(index < _ammsLength--, "Invalid index"); 41 | _amms[index] = _amms[_ammsLength]; 42 | delete _amms[_ammsLength]; 43 | } 44 | 45 | function add(address[] memory ammsToAdd) public override authorizedOnly { 46 | for(uint256 i = 0 ; i < ammsToAdd.length; i++) { 47 | IAMM amm = IAMM(_amms[_ammsLength++] = ammsToAdd[i]); 48 | (string memory name, uint256 version) = amm.info(); 49 | emit AMM(ammsToAdd[i], name, version); 50 | } 51 | } 52 | 53 | function findByLiquidityPool(address liquidityPoolAddress) public override view returns(uint256, uint256[] memory, address[] memory, address amm) { 54 | for(uint256 i = 0; i < _ammsLength; i++) { 55 | try IAMM(amm = _amms[i]).byLiquidityPool(liquidityPoolAddress) returns (uint256 liquidityPoolAmount, uint256[] memory tokensAmounts, address[] memory tokensAddresses) { 56 | if(tokensAddresses.length > 0) { 57 | return (liquidityPoolAmount, tokensAmounts, tokensAddresses, amm); 58 | } 59 | } catch { 60 | } 61 | amm = address(0); 62 | } 63 | } 64 | 65 | function info() public override view returns(string memory, uint256) {} 66 | 67 | function data() public override view returns(address, uint256, bool) {} 68 | 69 | function info(address liquidityPoolAddress) public override view returns(string memory name, uint256 version, address amm) { 70 | (,,,amm) = findByLiquidityPool(liquidityPoolAddress); 71 | (name, version) = IAMM(amm).info(); 72 | } 73 | 74 | function data(address liquidityPoolAddress) public override view returns(address ethereumAddress, uint256 maxTokensPerLiquidityPool, bool hasUniqueLiquidityPools, address amm) { 75 | (,,,amm) = findByLiquidityPool(liquidityPoolAddress); 76 | (ethereumAddress, maxTokensPerLiquidityPool, hasUniqueLiquidityPools) = IAMM(amm).data(); 77 | } 78 | 79 | function balanceOf(address liquidityPoolAddress, address owner) public override view returns(uint256, uint256[] memory, address[] memory) { 80 | (,,,address amm) = findByLiquidityPool(liquidityPoolAddress); 81 | return IAMM(amm).balanceOf(liquidityPoolAddress, owner); 82 | } 83 | 84 | function byLiquidityPool(address liquidityPoolAddress) public override view returns(uint256 liquidityPoolAmount, uint256[] memory tokensAmounts, address[] memory tokensAddresses) { 85 | (liquidityPoolAmount, tokensAmounts, tokensAddresses,) = findByLiquidityPool(liquidityPoolAddress); 86 | } 87 | 88 | function byTokens(address[] calldata liquidityPoolTokens) public override view returns(uint256, uint256[] memory, address, address[] memory) {} 89 | 90 | function byPercentage(address liquidityPoolAddress, uint256 numerator, uint256 denominator) public override view returns (uint256, uint256[] memory, address[] memory) { 91 | (,,,address amm) = findByLiquidityPool(liquidityPoolAddress); 92 | return IAMM(amm).byPercentage(liquidityPoolAddress, numerator, denominator); 93 | } 94 | 95 | function byLiquidityPoolAmount(address liquidityPoolAddress, uint256 liquidityPoolAmount) public override view returns(uint256[] memory, address[] memory) { 96 | (,,,address amm) = findByLiquidityPool(liquidityPoolAddress); 97 | return IAMM(amm).byLiquidityPoolAmount(liquidityPoolAddress, liquidityPoolAmount); 98 | } 99 | 100 | function byTokenAmount(address liquidityPoolAddress, address tokenAddress, uint256 tokenAmount) public override view returns(uint256, uint256[] memory, address[] memory) { 101 | (,,,address amm) = findByLiquidityPool(liquidityPoolAddress); 102 | return IAMM(amm).byTokenAmount(liquidityPoolAddress, tokenAddress, tokenAmount); 103 | } 104 | 105 | function createLiquidityPoolAndAddLiquidity(address[] calldata tokenAddresses, uint256[] calldata amounts, bool involvingETH, address receiver) public override payable returns(uint256, uint256[] memory, address, address[] memory) { 106 | revert("Impossibru"); 107 | } 108 | 109 | function addLiquidity(LiquidityPoolData calldata data) public override payable returns(uint256, uint256[] memory, address[] memory) { 110 | (,,,address amm) = findByLiquidityPool(data.liquidityPoolAddress); 111 | return IAMM(amm).addLiquidity(data); 112 | } 113 | 114 | function addLiquidityBatch(LiquidityPoolData[] calldata data) public override payable returns(uint256[] memory, uint256[][] memory, address[][] memory) { 115 | (,,,address amm) = findByLiquidityPool(data[0].liquidityPoolAddress); 116 | return IAMM(amm).addLiquidityBatch(data); 117 | } 118 | 119 | function removeLiquidity(LiquidityPoolData calldata data) public override returns(uint256, uint256[] memory, address[] memory) { 120 | (,,,address amm) = findByLiquidityPool(data.liquidityPoolAddress); 121 | return IAMM(amm).removeLiquidity(data); 122 | } 123 | 124 | function removeLiquidityBatch(LiquidityPoolData[] calldata data) public override returns(uint256[] memory, uint256[][] memory, address[][] memory) { 125 | (,,,address amm) = findByLiquidityPool(data[0].liquidityPoolAddress); 126 | return IAMM(amm).removeLiquidityBatch(data); 127 | } 128 | 129 | function getSwapOutput(address tokenAddress, uint256 tokenAmount, address[] calldata liquidityPoolAddresses, address[] calldata path) view public override returns(uint256[] memory) { 130 | (,,,address amm) = findByLiquidityPool(liquidityPoolAddresses[0]); 131 | return IAMM(amm).getSwapOutput(tokenAddress, tokenAmount, liquidityPoolAddresses, path); 132 | } 133 | 134 | function swapLiquidity(SwapData calldata data) public override payable returns(uint256) { 135 | (,,,address amm) = findByLiquidityPool(data.liquidityPoolAddresses[0]); 136 | return IAMM(amm).swapLiquidity(data); 137 | } 138 | 139 | function swapLiquidityBatch(SwapData[] calldata data) public override payable returns(uint256[] memory) { 140 | (,,,address amm) = findByLiquidityPool(data[0].liquidityPoolAddresses[0]); 141 | return IAMM(amm).swapLiquidityBatch(data); 142 | } 143 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/aggregator/IAMMAggregator.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../common/IAMM.sol"; 6 | 7 | interface IAMMAggregator is IAMM { 8 | 9 | function host() external view returns (address); 10 | 11 | function setHost(address newHost) external; 12 | 13 | function amms() external view returns (address[] memory); 14 | 15 | function remove(uint256) external; 16 | 17 | function add(address[] calldata) external; 18 | 19 | function findByLiquidityPool(address liquidityPoolAddress) external view returns(uint256, uint256[] memory, address[] memory, address); 20 | 21 | function info(address liquidityPoolAddress) external view returns(string memory name, uint256 version, address amm); 22 | 23 | function data(address liquidityPoolAddress) external view returns(address ethereumAddress, uint256 maxTokensPerLiquidityPool, bool hasUniqueLiquidityPools, address amm); 24 | 25 | event AMM(address indexed amm, string name, uint256 version); 26 | } 27 | 28 | interface IDoubleProxy { 29 | function proxy() external view returns (address); 30 | } 31 | 32 | interface IMVDProxy { 33 | function getMVDFunctionalitiesManagerAddress() external view returns(address); 34 | function getMVDWalletAddress() external view returns (address); 35 | function getStateHolderAddress() external view returns(address); 36 | } 37 | 38 | interface IMVDFunctionalitiesManager { 39 | function isAuthorizedFunctionality(address functionality) external view returns(bool); 40 | } 41 | 42 | interface IStateHolder { 43 | function getBool(string calldata varName) external view returns (bool); 44 | function getUint256(string calldata name) external view returns(uint256); 45 | function getAddress(string calldata name) external view returns(address); 46 | function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal); 47 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/common/AMMData.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | struct LiquidityPoolData { 5 | address liquidityPoolAddress; 6 | uint256 amount; 7 | address tokenAddress; 8 | bool amountIsLiquidityPool; 9 | bool involvingETH; 10 | address receiver; 11 | } 12 | 13 | struct SwapData { 14 | bool enterInETH; 15 | bool exitInETH; 16 | address[] liquidityPoolAddresses; 17 | address[] path; 18 | address inputToken; 19 | uint256 amount; 20 | address receiver; 21 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/common/IAMM.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./AMMData.sol"; 6 | 7 | interface IAMM { 8 | 9 | event NewLiquidityPoolAddress(address indexed); 10 | 11 | function info() external view returns(string memory name, uint256 version); 12 | 13 | function data() external view returns(address ethereumAddress, uint256 maxTokensPerLiquidityPool, bool hasUniqueLiquidityPools); 14 | 15 | function balanceOf(address liquidityPoolAddress, address owner) external view returns(uint256, uint256[] memory, address[] memory); 16 | 17 | function byLiquidityPool(address liquidityPoolAddress) external view returns(uint256, uint256[] memory, address[] memory); 18 | 19 | function byTokens(address[] calldata liquidityPoolTokens) external view returns(uint256, uint256[] memory, address, address[] memory); 20 | 21 | function byPercentage(address liquidityPoolAddress, uint256 numerator, uint256 denominator) external view returns (uint256, uint256[] memory, address[] memory); 22 | 23 | function byLiquidityPoolAmount(address liquidityPoolAddress, uint256 liquidityPoolAmount) external view returns(uint256[] memory, address[] memory); 24 | 25 | function byTokenAmount(address liquidityPoolAddress, address tokenAddress, uint256 tokenAmount) external view returns(uint256, uint256[] memory, address[] memory); 26 | 27 | function createLiquidityPoolAndAddLiquidity(address[] calldata tokenAddresses, uint256[] calldata amounts, bool involvingETH, address receiver) external payable returns(uint256, uint256[] memory, address, address[] memory); 28 | 29 | function addLiquidity(LiquidityPoolData calldata data) external payable returns(uint256, uint256[] memory, address[] memory); 30 | function addLiquidityBatch(LiquidityPoolData[] calldata data) external payable returns(uint256[] memory, uint256[][] memory, address[][] memory); 31 | 32 | function removeLiquidity(LiquidityPoolData calldata data) external returns(uint256, uint256[] memory, address[] memory); 33 | function removeLiquidityBatch(LiquidityPoolData[] calldata data) external returns(uint256[] memory, uint256[][] memory, address[][] memory); 34 | 35 | function getSwapOutput(address tokenAddress, uint256 tokenAmount, address[] calldata, address[] calldata path) view external returns(uint256[] memory); 36 | 37 | function swapLiquidity(SwapData calldata data) external payable returns(uint256); 38 | function swapLiquidityBatch(SwapData[] calldata data) external payable returns(uint256[] memory); 39 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/models/Balancer/1/IBalancerAMMV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../../../common/IAMM.sol"; 6 | import "../../../util/IERC20.sol"; 7 | 8 | interface IBalancerAMMV1 is IAMM { 9 | } 10 | 11 | interface IWETH { 12 | function deposit() external payable; 13 | 14 | function withdraw(uint wad) external; 15 | 16 | function totalSupply() external view returns (uint); 17 | 18 | function approve(address guy, uint wad) external returns (bool); 19 | 20 | function transfer(address dst, uint wad) external returns (bool); 21 | 22 | function transferFrom(address src, address dst, uint wad) 23 | external 24 | returns (bool); 25 | } 26 | 27 | interface BPool { 28 | 29 | function isPublicSwap() 30 | external view 31 | returns (bool); 32 | 33 | function isFinalized() 34 | external view 35 | returns (bool); 36 | 37 | function isBound(address t) 38 | external view 39 | returns (bool); 40 | 41 | function getNumTokens() 42 | external view 43 | returns (uint); 44 | 45 | function getCurrentTokens() 46 | external view 47 | returns (address[] memory tokens); 48 | 49 | function getFinalTokens() 50 | external view 51 | returns (address[] memory tokens); 52 | 53 | function getDenormalizedWeight(address token) 54 | external view 55 | returns (uint); 56 | 57 | function getTotalDenormalizedWeight() 58 | external view 59 | returns (uint); 60 | 61 | function getNormalizedWeight(address token) 62 | external view 63 | returns (uint); 64 | 65 | function getBalance(address token) 66 | external view 67 | returns (uint); 68 | 69 | function getSwapFee() 70 | external view 71 | returns (uint); 72 | 73 | function getController() 74 | external view 75 | returns (address); 76 | 77 | function calcOutGivenIn( 78 | uint tokenBalanceIn, 79 | uint tokenWeightIn, 80 | uint tokenBalanceOut, 81 | uint tokenWeightOut, 82 | uint tokenAmountIn, 83 | uint swapFee 84 | ) 85 | external pure 86 | returns (uint tokenAmountOut); 87 | 88 | function calcInGivenOut( 89 | uint tokenBalanceIn, 90 | uint tokenWeightIn, 91 | uint tokenBalanceOut, 92 | uint tokenWeightOut, 93 | uint tokenAmountOut, 94 | uint swapFee 95 | ) 96 | external pure 97 | returns (uint tokenAmountIn); 98 | 99 | function setSwapFee(uint swapFee) 100 | external; 101 | 102 | function setController(address manager) 103 | external; 104 | 105 | function setPublicSwap(bool public_) 106 | external; 107 | 108 | function finalize() 109 | external; 110 | 111 | function bind(address token, uint balance, uint denorm) 112 | external; 113 | 114 | function rebind(address token, uint balance, uint denorm) 115 | external; 116 | 117 | function unbind(address token) 118 | external; 119 | 120 | function gulp(address token) 121 | external; 122 | 123 | function getSpotPrice(address tokenIn, address tokenOut) 124 | external view 125 | returns (uint spotPrice); 126 | 127 | function getSpotPriceSansFee(address tokenIn, address tokenOut) 128 | external view 129 | returns (uint spotPrice); 130 | 131 | function joinPool(uint poolAmountOut, uint[] calldata maxAmountsIn) 132 | external; 133 | 134 | function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut) 135 | external; 136 | 137 | function swapExactAmountIn( 138 | address tokenIn, 139 | uint tokenAmountIn, 140 | address tokenOut, 141 | uint minAmountOut, 142 | uint maxPrice 143 | ) 144 | external 145 | returns (uint tokenAmountOut, uint spotPriceAfter); 146 | 147 | function swapExactAmountOut( 148 | address tokenIn, 149 | uint maxAmountIn, 150 | address tokenOut, 151 | uint tokenAmountOut, 152 | uint maxPrice 153 | ) 154 | external 155 | returns (uint tokenAmountIn, uint spotPriceAfter); 156 | 157 | function joinswapExternAmountIn(address tokenIn, uint tokenAmountIn, uint minPoolAmountOut) 158 | external 159 | returns (uint poolAmountOut); 160 | 161 | function joinswapPoolAmountOut(address tokenIn, uint poolAmountOut, uint maxAmountIn) 162 | external 163 | returns (uint tokenAmountIn); 164 | 165 | function exitswapPoolAmountIn(address tokenOut, uint poolAmountIn, uint minAmountOut) 166 | external 167 | returns (uint tokenAmountOut); 168 | 169 | function exitswapExternAmountOut(address tokenOut, uint tokenAmountOut, uint maxPoolAmountIn) 170 | external 171 | returns (uint poolAmountIn); 172 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/models/Mooniswap/1/IMooniswapAMMV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../../../common/IAMM.sol"; 6 | import "../../../util/IERC20.sol"; 7 | 8 | interface IMooniswapAMMV1 is IAMM { 9 | 10 | function factory() external view returns(address); 11 | } 12 | 13 | contract IMooniFactory { 14 | 15 | mapping(address => mapping(address => Mooniswap)) public pools; 16 | 17 | function deploy(address tokenA, address tokenB) external returns(Mooniswap pool) {} 18 | function sortTokens(address tokenA, address tokenB) external pure returns(address, address) {} 19 | } 20 | 21 | interface Mooniswap { 22 | 23 | function fee() external view returns(uint256); 24 | 25 | function getTokens() external view returns(address[] memory); 26 | 27 | function decayPeriod() external pure returns(uint256); 28 | 29 | function getBalanceForAddition(address token) external view returns(uint256); 30 | 31 | function getBalanceForRemoval(address token) external view returns(uint256); 32 | 33 | function getReturn(address src, address dst, uint256 amount) external view returns(uint256); 34 | 35 | function deposit(uint256[] calldata amounts, uint256[] calldata minAmounts) external payable returns(uint256 fairSupply); 36 | 37 | function withdraw(uint256 amount, uint256[] memory minReturns) external; 38 | 39 | function swap(address src, address dst, uint256 amount, uint256 minReturn, address referral) external payable returns(uint256 result); 40 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/models/Mooniswap/1/MooniswapAMMV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./IMooniswapAMMV1.sol"; 6 | import "../../../common/AMM.sol"; 7 | 8 | contract MooniswapAMMV1 is IMooniswapAMMV1, AMM { 9 | 10 | address public override immutable factory; 11 | 12 | constructor(address factoryAddress) AMM("Mooniswap", 1, address(0), 2, true) { 13 | factory = factoryAddress; 14 | } 15 | 16 | function _getLiquidityPoolOperator(address, address[] memory) internal override virtual view returns(address) { 17 | return address(0); 18 | } 19 | 20 | function byLiquidityPool(address liquidityPoolAddress) public override view returns(uint256 liquidityPoolAmount, uint256[] memory tokensAmounts, address[] memory tokenAddresses) { 21 | 22 | Mooniswap mooniswap = Mooniswap(liquidityPoolAddress); 23 | 24 | liquidityPoolAmount = IERC20(liquidityPoolAddress).totalSupply(); 25 | 26 | tokensAmounts = new uint256[]((tokenAddresses = mooniswap.getTokens()).length); 27 | for(uint256 i = 0; i < tokensAmounts.length; i++) { 28 | tokensAmounts[i] = mooniswap.getBalanceForRemoval(tokenAddresses[i]); 29 | } 30 | } 31 | 32 | function byTokens(address[] memory tokens) public override view returns(uint256 liquidityPoolAmount, uint256[] memory tokensAmounts, address liquidityPoolAddress, address[] memory orderedTokens) { 33 | 34 | Mooniswap mooniswap = IMooniFactory(factory).pools(tokens[0], tokens[1]); 35 | 36 | if(address(mooniswap) == address(0)) { 37 | return (liquidityPoolAmount, tokensAmounts, liquidityPoolAddress, orderedTokens); 38 | } 39 | 40 | orderedTokens = mooniswap.getTokens(); 41 | 42 | liquidityPoolAmount = IERC20(liquidityPoolAddress = address(mooniswap)).totalSupply(); 43 | 44 | tokensAmounts = new uint256[](orderedTokens.length); 45 | for(uint256 i = 0; i < tokensAmounts.length; i++) { 46 | tokensAmounts[i] = mooniswap.getBalanceForRemoval(orderedTokens[i]); 47 | } 48 | } 49 | 50 | function getSwapOutput(address tokenAddress, uint256 tokenAmount, address[] calldata liquidityPoolAddresses, address[] calldata path) view public virtual override returns(uint256[] memory realAmounts) { 51 | realAmounts = new uint256[](path.length + 1); 52 | realAmounts[0] = tokenAmount; 53 | for(uint256 i = 0 ; i < path.length; i++) { 54 | realAmounts[i + 1] = Mooniswap(liquidityPoolAddresses[i]).getReturn(i == 0 ? tokenAddress : path[i - 1], path[i], realAmounts[i]); 55 | } 56 | } 57 | 58 | function _getLiquidityPoolCreator(address[] memory, uint256[] memory, bool) internal virtual view override returns(address) { 59 | return address(0); 60 | } 61 | 62 | function _createLiquidityPoolAndAddLiquidity(address[] memory tokenAddresses, uint256[] memory amounts, bool, address, address receiver) internal virtual override returns(uint256 liquidityPoolAmount, uint256[] memory tokensAmounts, address liquidityPoolAddress, address[] memory orderedTokens) { 63 | 64 | Mooniswap mooniswap = IMooniFactory(factory).deploy(tokenAddresses[0], tokenAddresses[1]); 65 | liquidityPoolAddress = address(mooniswap); 66 | orderedTokens = mooniswap.getTokens(); 67 | 68 | tokensAmounts = new uint256[](orderedTokens.length); 69 | tokensAmounts[0] = amounts[orderedTokens[0] == tokenAddresses[0] ? 0 : 1]; 70 | tokensAmounts[1] = amounts[orderedTokens[1] == tokenAddresses[1] ? 1 : 0]; 71 | 72 | for(uint256 i = 0; i < orderedTokens.length; i++) { 73 | if(orderedTokens[i] != _ethereumAddress) { 74 | _safeApprove(orderedTokens[i], liquidityPoolAddress, tokensAmounts[i]); 75 | } 76 | } 77 | 78 | if(orderedTokens[0] != _ethereumAddress && orderedTokens[1] != _ethereumAddress) { 79 | mooniswap.deposit(tokensAmounts, tokensAmounts); 80 | } else { 81 | mooniswap.deposit{value : orderedTokens[0] == _ethereumAddress ? tokensAmounts[0] : tokensAmounts[1]}(tokensAmounts, tokensAmounts); 82 | } 83 | 84 | _safeTransfer(liquidityPoolAddress, receiver, liquidityPoolAmount = IERC20(liquidityPoolAddress).balanceOf(address(this))); 85 | } 86 | 87 | function _addLiquidity(ProcessedLiquidityPoolData memory data) internal override virtual returns(uint256 liquidityPoolAmount, uint256[] memory tokensAmounts) { 88 | 89 | Mooniswap mooniswap = Mooniswap(data.liquidityPoolAddress); 90 | 91 | liquidityPoolAmount = data.liquidityPoolAmount; 92 | tokensAmounts = data.tokensAmounts; 93 | 94 | for(uint256 i = 0; i < data.liquidityPoolTokens.length; i++) { 95 | if(data.liquidityPoolTokens[i] != _ethereumAddress) { 96 | _safeApprove(data.liquidityPoolTokens[i], data.liquidityPoolAddress, data.tokensAmounts[i]); 97 | } 98 | } 99 | 100 | if(data.liquidityPoolTokens[0] != _ethereumAddress && data.liquidityPoolTokens[1] != _ethereumAddress) { 101 | mooniswap.deposit(data.tokensAmounts, new uint256[](data.tokensAmounts.length)); 102 | } else { 103 | mooniswap.deposit{value : data.liquidityPoolTokens[0] == _ethereumAddress ? data.tokensAmounts[0] : data.tokensAmounts[1]}(data.tokensAmounts, new uint256[](data.tokensAmounts.length)); 104 | } 105 | _safeTransfer(data.liquidityPoolAddress, data.receiver, liquidityPoolAmount = IERC20(data.liquidityPoolAddress).balanceOf(address(this))); 106 | } 107 | 108 | function _removeLiquidity(ProcessedLiquidityPoolData memory data) internal override virtual returns(uint256 liquidityPoolAmount, uint256[] memory tokensAmounts) { 109 | 110 | Mooniswap(data.liquidityPoolAddress).withdraw(liquidityPoolAmount = data.liquidityPoolAmount, new uint256[](2)); 111 | 112 | tokensAmounts = new uint256[](data.tokensAmounts.length); 113 | for(uint256 i = 0; i < data.tokensAmounts.length; i++) { 114 | if(data.liquidityPoolTokens[i] != _ethereumAddress) { 115 | _safeTransfer(data.liquidityPoolTokens[i], data.receiver, data.tokensAmounts[i] = IERC20(data.liquidityPoolTokens[i]).balanceOf(address(this))); 116 | } else { 117 | (bool result,) = data.receiver.call{value:tokensAmounts[i] = address(this).balance}(""); 118 | require(result, "ETH transfer failed"); 119 | } 120 | } 121 | } 122 | 123 | function _swapLiquidity(ProcessedSwapData memory data) internal override virtual returns(uint256 outputAmount) { 124 | outputAmount = data.amount; 125 | for(uint256 i = 0; i < data.liquidityPoolAddresses.length; i++) { 126 | address inputToken = i == 0 ? data.inputToken : data.path[i - 1]; 127 | if(inputToken != _ethereumAddress) { 128 | _safeApprove(inputToken, data.liquidityPoolAddresses[i], outputAmount); 129 | } 130 | if(inputToken == _ethereumAddress) { 131 | outputAmount = Mooniswap(data.liquidityPoolAddresses[i]).swap{value : outputAmount}(inputToken, data.path[i], outputAmount, 0, address(0)); 132 | } else { 133 | outputAmount = Mooniswap(data.liquidityPoolAddresses[i]).swap(inputToken, data.path[i], outputAmount, 0, address(0)); 134 | } 135 | } 136 | if(data.path[data.path.length - 1] == _ethereumAddress) { 137 | (bool result,) = data.receiver.call{value:outputAmount}(""); 138 | require(result, "ETH transfer failed"); 139 | } else { 140 | _safeTransfer(data.path[data.path.length - 1], data.receiver, outputAmount); 141 | } 142 | } 143 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/models/SushiSwap/1/ISushiSwapAMMV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../../../common/IAMM.sol"; 6 | import "../../../util/IERC20.sol"; 7 | 8 | interface ISushiSwapAMMV1 is IAMM { 9 | 10 | function sushiSwapData() external view returns(address routerAddress, address wethAddress); 11 | } 12 | 13 | interface IUniswapV2Router { 14 | function factory() external pure returns (address); 15 | function WETH() external pure returns (address); 16 | 17 | function addLiquidity( 18 | address tokenA, 19 | address tokenB, 20 | uint amountADesired, 21 | uint amountBDesired, 22 | uint amountAMin, 23 | uint amountBMin, 24 | address to, 25 | uint deadline 26 | ) external returns (uint amountA, uint amountB, uint liquidity); 27 | function addLiquidityETH( 28 | address token, 29 | uint amountTokenDesired, 30 | uint amountTokenMin, 31 | uint amountETHMin, 32 | address to, 33 | uint deadline 34 | ) external payable returns (uint amountToken, uint amountETH, uint liquidity); 35 | function removeLiquidity( 36 | address tokenA, 37 | address tokenB, 38 | uint liquidity, 39 | uint amountAMin, 40 | uint amountBMin, 41 | address to, 42 | uint deadline 43 | ) external returns (uint amountA, uint amountB); 44 | function removeLiquidityETH( 45 | address token, 46 | uint liquidity, 47 | uint amountTokenMin, 48 | uint amountETHMin, 49 | address to, 50 | uint deadline 51 | ) external returns (uint amountToken, uint amountETH); 52 | function removeLiquidityWithPermit( 53 | address tokenA, 54 | address tokenB, 55 | uint liquidity, 56 | uint amountAMin, 57 | uint amountBMin, 58 | address to, 59 | uint deadline, 60 | bool approveMax, uint8 v, bytes32 r, bytes32 s 61 | ) external returns (uint amountA, uint amountB); 62 | function removeLiquidityETHWithPermit( 63 | address token, 64 | uint liquidity, 65 | uint amountTokenMin, 66 | uint amountETHMin, 67 | address to, 68 | uint deadline, 69 | bool approveMax, uint8 v, bytes32 r, bytes32 s 70 | ) external returns (uint amountToken, uint amountETH); 71 | function swapExactTokensForTokens( 72 | uint amountIn, 73 | uint amountOutMin, 74 | address[] calldata path, 75 | address to, 76 | uint deadline 77 | ) external returns (uint[] memory amounts); 78 | function swapTokensForExactTokens( 79 | uint amountOut, 80 | uint amountInMax, 81 | address[] calldata path, 82 | address to, 83 | uint deadline 84 | ) external returns (uint[] memory amounts); 85 | function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 86 | external 87 | payable 88 | returns (uint[] memory amounts); 89 | function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 90 | external 91 | returns (uint[] memory amounts); 92 | function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 93 | external 94 | returns (uint[] memory amounts); 95 | function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 96 | external 97 | payable 98 | returns (uint[] memory amounts); 99 | 100 | function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 101 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); 102 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); 103 | function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 104 | function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 105 | } 106 | 107 | interface IUniswapV2Factory { 108 | function getPair(address tokenA, address tokenB) external view returns (address pair); 109 | } 110 | 111 | interface IUniswapV2Pair is IERC20 { 112 | function token0() external view returns (address); 113 | function token1() external view returns (address); 114 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 115 | function factory() external view returns(address); 116 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/models/UniswapV2/1/IUniswapV2AMMV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../../../common/IAMM.sol"; 6 | import "../../../util/IERC20.sol"; 7 | 8 | interface IUniswapV2AMMV1 is IAMM { 9 | 10 | function uniswapData() external view returns(address routerAddress, address wethAddress); 11 | } 12 | 13 | interface IUniswapV2Router { 14 | function factory() external pure returns (address); 15 | function WETH() external pure returns (address); 16 | 17 | function addLiquidity( 18 | address tokenA, 19 | address tokenB, 20 | uint amountADesired, 21 | uint amountBDesired, 22 | uint amountAMin, 23 | uint amountBMin, 24 | address to, 25 | uint deadline 26 | ) external returns (uint amountA, uint amountB, uint liquidity); 27 | function addLiquidityETH( 28 | address token, 29 | uint amountTokenDesired, 30 | uint amountTokenMin, 31 | uint amountETHMin, 32 | address to, 33 | uint deadline 34 | ) external payable returns (uint amountToken, uint amountETH, uint liquidity); 35 | function removeLiquidity( 36 | address tokenA, 37 | address tokenB, 38 | uint liquidity, 39 | uint amountAMin, 40 | uint amountBMin, 41 | address to, 42 | uint deadline 43 | ) external returns (uint amountA, uint amountB); 44 | function removeLiquidityETH( 45 | address token, 46 | uint liquidity, 47 | uint amountTokenMin, 48 | uint amountETHMin, 49 | address to, 50 | uint deadline 51 | ) external returns (uint amountToken, uint amountETH); 52 | function removeLiquidityWithPermit( 53 | address tokenA, 54 | address tokenB, 55 | uint liquidity, 56 | uint amountAMin, 57 | uint amountBMin, 58 | address to, 59 | uint deadline, 60 | bool approveMax, uint8 v, bytes32 r, bytes32 s 61 | ) external returns (uint amountA, uint amountB); 62 | function removeLiquidityETHWithPermit( 63 | address token, 64 | uint liquidity, 65 | uint amountTokenMin, 66 | uint amountETHMin, 67 | address to, 68 | uint deadline, 69 | bool approveMax, uint8 v, bytes32 r, bytes32 s 70 | ) external returns (uint amountToken, uint amountETH); 71 | function swapExactTokensForTokens( 72 | uint amountIn, 73 | uint amountOutMin, 74 | address[] calldata path, 75 | address to, 76 | uint deadline 77 | ) external returns (uint[] memory amounts); 78 | function swapTokensForExactTokens( 79 | uint amountOut, 80 | uint amountInMax, 81 | address[] calldata path, 82 | address to, 83 | uint deadline 84 | ) external returns (uint[] memory amounts); 85 | function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 86 | external 87 | payable 88 | returns (uint[] memory amounts); 89 | function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 90 | external 91 | returns (uint[] memory amounts); 92 | function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 93 | external 94 | returns (uint[] memory amounts); 95 | function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 96 | external 97 | payable 98 | returns (uint[] memory amounts); 99 | 100 | function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 101 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); 102 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); 103 | function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 104 | function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 105 | } 106 | 107 | interface IUniswapV2Factory { 108 | function getPair(address tokenA, address tokenB) external view returns (address pair); 109 | } 110 | 111 | interface IUniswapV2Pair is IERC20 { 112 | function token0() external view returns (address); 113 | function token1() external view returns (address); 114 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 115 | function factory() external view returns(address); 116 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/models/UniswapV3/1/IUniswapV3AMMV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../../../common/IAMM.sol"; 6 | 7 | interface IUniswapV3AMMV1 is IAMM { 8 | 9 | function uniswapData() external view returns(address factoryAddress, address swapRouterAddress, address nonfungiblePositionManagerAddress, address quoterAddress, address wethAddress); 10 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/util/ERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | import "./IERC165.sol"; 5 | 6 | contract ERC165 is IERC165 { 7 | bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; 8 | 9 | mapping(bytes4 => bool) private _supportedInterfaces; 10 | 11 | constructor () { 12 | _registerInterface(_INTERFACE_ID_ERC165); 13 | } 14 | 15 | function supportsInterface(bytes4 interfaceId) public view override returns (bool) { 16 | return _supportedInterfaces[interfaceId]; 17 | } 18 | 19 | function _registerInterface(bytes4 interfaceId) internal virtual { 20 | require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); 21 | _supportedInterfaces[interfaceId] = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/amm-aggregator/util/IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | interface IERC165 { 5 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 6 | } -------------------------------------------------------------------------------- /contracts/amm-aggregator/util/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | interface IERC20 { 5 | function totalSupply() external view returns(uint256); 6 | function balanceOf(address account) external view returns (uint256); 7 | function allowance(address owner, address spender) external view returns (uint256); 8 | function approve(address spender, uint256 amount) external returns (bool); 9 | function transfer(address recipient, uint256 amount) external returns (bool); 10 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 11 | 12 | function decimals() external view returns (uint8); 13 | } -------------------------------------------------------------------------------- /contracts/farming/FarmData.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | struct FarmingPositionRequest { 5 | uint256 setupIndex; // index of the chosen setup. 6 | uint256 amount0; // amount of main token or liquidity pool token. 7 | uint256 amount1; // amount of other token or liquidity pool token. Needed for gen2 8 | address positionOwner; // position extension or address(0) [msg.sender]. 9 | uint256 amount0Min; 10 | uint256 amount1Min; 11 | } 12 | 13 | struct FarmingSetupConfiguration { 14 | bool add; // true if we're adding a new setup, false we're updating it. 15 | bool disable; 16 | uint256 index; // index of the setup we're updating. 17 | FarmingSetupInfo info; // data of the new or updated setup 18 | } 19 | 20 | struct FarmingSetupInfo { 21 | uint256 eventDuration; // duration of setup 22 | uint256 startEvent; // optional start event used for the delayed activation of the first setup 23 | uint256 originalRewardPerEvent; 24 | uint256 minStakeable; // minimum amount of staking tokens. 25 | uint256 renewTimes; // if the setup is renewable or if it's one time. 26 | address liquidityPoolTokenAddress; // address of the liquidity pool token 27 | address mainTokenAddress; // eg. buidl address. 28 | bool involvingETH; // if the setup involves ETH or not. 29 | uint256 setupsCount; // number of setups created by this info. 30 | uint256 lastSetupIndex; // index of last setup; 31 | int24 tickLower; // Gen2 Only - tickLower of the UniswapV3 pool 32 | int24 tickUpper; // Gen 2 Only - tickUpper of the UniswapV3 pool 33 | } 34 | 35 | struct FarmingSetup { 36 | uint256 infoIndex; // setup info 37 | bool active; // if the setup is active or not. 38 | uint256 startEvent; // farming setup start event. 39 | uint256 endEvent; // farming setup end event. 40 | uint256 lastUpdateEvent; // number of the event where an update was triggered. 41 | uint256 objectId; // need for gen2. uniswapV3 NFT position Id 42 | uint256 rewardPerEvent; // farming setup reward per single event. 43 | uint128 totalSupply; // Total LP token liquidity of all the positions of this setup 44 | } 45 | 46 | struct FarmingPosition { 47 | address uniqueOwner; // address representing the owner of the position. 48 | uint256 setupIndex; // the setup index related to this position. 49 | uint256 creationEvent; // event when this position was created. 50 | uint128 liquidityPoolTokenAmount; // amount of liquidity pool token in the position. 51 | uint256 reward; // position reward. 52 | } -------------------------------------------------------------------------------- /contracts/farming/FarmDataGen1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | struct FarmingPositionRequest { 5 | uint256 setupIndex; // index of the chosen setup. 6 | uint256 amount; // amount of main token or liquidity pool token. 7 | bool amountIsLiquidityPool; //true if user wants to directly share the liquidity pool token amount, false to add liquidity to AMM 8 | address positionOwner; // position extension or address(0) [msg.sender]. 9 | uint256 amount0Min; 10 | uint256 amount1Min; 11 | } 12 | 13 | struct FarmingSetupConfiguration { 14 | bool add; // true if we're adding a new setup, false we're updating it. 15 | bool disable; 16 | uint256 index; // index of the setup we're updating. 17 | FarmingSetupInfo info; // data of the new or updated setup 18 | } 19 | 20 | struct FarmingSetupInfo { 21 | bool free; // if the setup is a free farming setup or a locked one. 22 | uint256 eventDuration; // duration of setup 23 | uint256 startEvent; // optional start event used for the delayed activation of the first setup 24 | uint256 originalRewardPerEvent; 25 | uint256 minStakeable; // minimum amount of staking tokens. 26 | uint256 maxStakeable; // maximum amount stakeable in the setup (used only if free is false). 27 | uint256 renewTimes; // if the setup is renewable or if it's one time. 28 | address ammPlugin; // amm plugin address used for this setup (eg. uniswap amm plugin address). 29 | address liquidityPoolTokenAddress; // address of the liquidity pool token 30 | address mainTokenAddress; // eg. buidl address. 31 | address ethereumAddress; 32 | bool involvingETH; // if the setup involves ETH or not. 33 | uint256 penaltyFee; // fee paid when the user exits a still active locked farming setup (used only if free is false). 34 | uint256 setupsCount; // number of setups created by this info. 35 | uint256 lastSetupIndex; // index of last setup; 36 | } 37 | 38 | struct FarmingSetup { 39 | uint256 infoIndex; // setup info 40 | bool active; // if the setup is active or not. 41 | uint256 startEvent; // farming setup start event. 42 | uint256 endEvent; // farming setup end event. 43 | uint256 lastUpdateEvent; // number of the event where an update was triggered. 44 | uint256 objectId; // items object id for the liquidity pool token (used only if free is false). 45 | uint256 rewardPerEvent; // farming setup reward per single event. 46 | uint256 totalSupply; // If free it's the LP amount, if locked is currentlyStaked. 47 | } 48 | 49 | struct FarmingPosition { 50 | address uniqueOwner; // address representing the owner of the position. 51 | uint256 setupIndex; // the setup index related to this position. 52 | uint256 creationEvent; // event when this position was created. 53 | uint256 liquidityPoolTokenAmount; // amount of liquidity pool token in the position. 54 | uint256 mainTokenAmount; // amount of main token in the position (used only if free is false). 55 | uint256 reward; // position reward (used only if free is false). 56 | uint256 lockedRewardPerEvent; // position locked reward per event (used only if free is false). 57 | } -------------------------------------------------------------------------------- /contracts/farming/FarmDataRegular.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | struct FarmingPositionRequest { 5 | uint256 setupIndex; // index of the chosen setup. 6 | uint256 amount0; // amount of main token or liquidity pool token. 7 | uint256 amount1; // amount of other token or liquidity pool token. Needed for gen2 8 | address positionOwner; // position extension or address(0) [msg.sender]. 9 | uint256 amount0Min; 10 | uint256 amount1Min; 11 | } 12 | 13 | struct FarmingSetupConfiguration { 14 | bool add; // true if we're adding a new setup, false we're updating it. 15 | bool disable; 16 | uint256 index; // index of the setup we're updating. 17 | FarmingSetupInfo info; // data of the new or updated setup 18 | } 19 | 20 | struct FarmingSetupInfo { 21 | uint256 eventDuration; // duration of setup 22 | uint256 startEvent; // optional start event used for the delayed activation of the first setup 23 | uint256 originalRewardPerEvent; 24 | uint256 minStakeable; // minimum amount of staking tokens. 25 | uint256 renewTimes; // if the setup is renewable or if it's one time. 26 | address liquidityPoolTokenAddress; // address of the liquidity pool token 27 | address mainTokenAddress; // eg. buidl address. 28 | bool involvingETH; // if the setup involves ETH or not. 29 | uint256 setupsCount; // number of setups created by this info. 30 | uint256 lastSetupIndex; // index of last setup; 31 | int24 tickLower; // Gen2 Only - tickLower of the UniswapV3 pool 32 | int24 tickUpper; // Gen 2 Only - tickUpper of the UniswapV3 pool 33 | } 34 | 35 | struct FarmingSetup { 36 | uint256 infoIndex; // setup info 37 | bool active; // if the setup is active or not. 38 | uint256 startEvent; // farming setup start event. 39 | uint256 endEvent; // farming setup end event. 40 | uint256 lastUpdateEvent; // number of the event where an update was triggered. 41 | uint256 deprecatedObjectId; // need for gen2. uniswapV3 NFT position Id 42 | uint256 rewardPerEvent; // farming setup reward per single event. 43 | uint128 totalSupply; // Total LP token liquidity of all the positions of this setup 44 | } 45 | 46 | struct FarmingPosition { 47 | address uniqueOwner; // address representing the owner of the position. 48 | uint256 setupIndex; // the setup index related to this position. 49 | uint256 creationEvent; // event when this position was created. 50 | uint256 tokenId; // amount of liquidity pool token in the position. 51 | uint256 reward; // position reward. 52 | } -------------------------------------------------------------------------------- /contracts/farming/FarmExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./IFarmExtension.sol"; 6 | import "./IFarmMain.sol"; 7 | import "./util/IERC20.sol"; 8 | import "./util/IERC20Mintable.sol"; 9 | 10 | contract FarmExtension is IFarmExtension { 11 | 12 | // wallet who has control on the extension and treasury 13 | address internal _host; 14 | address internal _treasury; 15 | // address of the farm main contract linked to this extension 16 | address internal _farmMainContract; 17 | // the reward token address linked to this extension 18 | address internal _rewardTokenAddress; 19 | // whether the token is by mint or by reserve 20 | bool internal _byMint; 21 | 22 | /** MODIFIERS */ 23 | 24 | /** @dev farmMainOnly modifier used to check for unauthorized transfers. */ 25 | modifier farmMainOnly() { 26 | require(msg.sender == _farmMainContract, "Unauthorized"); 27 | _; 28 | } 29 | 30 | /** @dev hostOnly modifier used to check for unauthorized edits. */ 31 | modifier hostOnly() { 32 | require(msg.sender == _host, "Unauthorized"); 33 | _; 34 | } 35 | 36 | /** PUBLIC METHODS */ 37 | 38 | receive() external payable { 39 | require(_farmMainContract != address(0) && _rewardTokenAddress == address(0), "ETH not allowed"); 40 | } 41 | 42 | function init(bool byMint, address host, address treasury) public virtual override { 43 | require(_farmMainContract == address(0), "Already init"); 44 | require((_host = host) != address(0), "blank host"); 45 | _rewardTokenAddress = IFarmMain(_farmMainContract = msg.sender)._rewardTokenAddress(); 46 | _byMint = byMint; 47 | _treasury = treasury != address(0) ? treasury : host; 48 | } 49 | 50 | function data() view public virtual override returns(address farmMainContract, bool byMint, address host, address treasury, address rewardTokenAddress) { 51 | return (_farmMainContract, _byMint, _host, _treasury, _rewardTokenAddress); 52 | } 53 | 54 | /** @dev method used to update the extension host. 55 | * @param host new host address. 56 | */ 57 | function setHost(address host) public virtual override hostOnly { 58 | _host = host; 59 | } 60 | 61 | /** @dev method used to update the extension treasury. 62 | * @param treasury new treasury address. 63 | */ 64 | function setTreasury(address treasury) public virtual override hostOnly { 65 | _treasury = treasury; 66 | } 67 | 68 | /** @dev this function calls the farm main contract with the given address and sets the given farming setups. 69 | * @param farmingSetups array containing all the farming setups. 70 | */ 71 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) public virtual override hostOnly { 72 | IFarmMain(_farmMainContract).setFarmingSetups(farmingSetups); 73 | } 74 | 75 | /** @dev transfers the input amount to the caller farming contract. 76 | * @param amount amount of erc20 to transfer or mint. 77 | */ 78 | function transferTo(uint256 amount) public virtual override farmMainOnly { 79 | if(_rewardTokenAddress != address(0)) { 80 | return _byMint ? _mintAndTransfer(_rewardTokenAddress, _farmMainContract, amount) : _safeTransfer(_rewardTokenAddress, _farmMainContract, amount); 81 | } 82 | (bool result, ) = _farmMainContract.call{value:amount}(""); 83 | require(result, "ETH transfer failed."); 84 | } 85 | 86 | /** @dev transfers the input amount from the caller farming contract to the extension. 87 | * @param amount amount of erc20 to transfer back or burn. 88 | */ 89 | function backToYou(uint256 amount) payable public virtual override farmMainOnly { 90 | if(_rewardTokenAddress != address(0)) { 91 | _safeTransferFrom(_rewardTokenAddress, msg.sender, _byMint ? address(this) : _treasury, amount); 92 | if(_byMint) { 93 | _burn(_rewardTokenAddress, amount); 94 | } 95 | } else { 96 | require(msg.value == amount, "invalid sent amount"); 97 | if(_treasury != address(this)) { 98 | (bool result, ) = _treasury.call{value:amount}(""); 99 | require(result, "ETH transfer failed."); 100 | } 101 | } 102 | } 103 | 104 | /** INTERNAL METHODS */ 105 | 106 | function _mintAndTransfer(address erc20TokenAddress, address recipient, uint256 value) internal virtual { 107 | IERC20Mintable(erc20TokenAddress).mint(recipient, value); 108 | } 109 | 110 | function _burn(address erc20TokenAddress, uint256 value) internal virtual { 111 | IERC20Mintable(erc20TokenAddress).burn(msg.sender, value); 112 | } 113 | 114 | /** @dev function used to safely approve ERC20 transfers. 115 | * @param erc20TokenAddress address of the token to approve. 116 | * @param to receiver of the approval. 117 | * @param value amount to approve for. 118 | */ 119 | function _safeApprove(address erc20TokenAddress, address to, uint256 value) internal virtual { 120 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, to, value)); 121 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); 122 | } 123 | 124 | /** @dev function used to safe transfer ERC20 tokens. 125 | * @param erc20TokenAddress address of the token to transfer. 126 | * @param to receiver of the tokens. 127 | * @param value amount of tokens to transfer. 128 | */ 129 | function _safeTransfer(address erc20TokenAddress, address to, uint256 value) internal virtual { 130 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); 131 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); 132 | } 133 | 134 | /** @dev this function safely transfers the given ERC20 value from an address to another. 135 | * @param erc20TokenAddress erc20 token address. 136 | * @param from address from. 137 | * @param to address to. 138 | * @param value amount to transfer. 139 | */ 140 | function _safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal virtual { 141 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); 142 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); 143 | } 144 | 145 | /** @dev calls the contract at the given location using the given payload and returns the returnData. 146 | * @param location location to call. 147 | * @param payload call payload. 148 | * @return returnData call return data. 149 | */ 150 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 151 | assembly { 152 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 153 | let size := returndatasize() 154 | returnData := mload(0x40) 155 | mstore(returnData, size) 156 | let returnDataPayloadStart := add(returnData, 0x20) 157 | returndatacopy(returnDataPayloadStart, 0, size) 158 | mstore(0x40, add(returnDataPayloadStart, size)) 159 | switch result case 0 {revert(returnDataPayloadStart, size)} 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /contracts/farming/FarmExtensionGen1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./IFarmExtensionGen1.sol"; 6 | import "./IFarmMainGen1.sol"; 7 | import "./util/IERC20.sol"; 8 | import "./util/IERC20Mintable.sol"; 9 | 10 | contract FarmExtensionGen1 is IFarmExtensionGen1 { 11 | 12 | // wallet who has control on the extension and treasury 13 | address internal _host; 14 | address internal _treasury; 15 | // address of the farm main contract linked to this extension 16 | address internal _farmMainContract; 17 | // the reward token address linked to this extension 18 | address internal _rewardTokenAddress; 19 | // whether the token is by mint or by reserve 20 | bool internal _byMint; 21 | 22 | /** MODIFIERS */ 23 | 24 | /** @dev farmMainOnly modifier used to check for unauthorized transfers. */ 25 | modifier farmMainOnly() { 26 | require(msg.sender == _farmMainContract, "Unauthorized"); 27 | _; 28 | } 29 | 30 | /** @dev hostOnly modifier used to check for unauthorized edits. */ 31 | modifier hostOnly() { 32 | require(msg.sender == _host, "Unauthorized"); 33 | _; 34 | } 35 | 36 | /** PUBLIC METHODS */ 37 | 38 | receive() external payable { 39 | require(_farmMainContract != address(0) && _rewardTokenAddress == address(0), "ETH not allowed"); 40 | } 41 | 42 | function init(bool byMint, address host, address treasury) public virtual override { 43 | require(_farmMainContract == address(0), "Already init"); 44 | require((_host = host) != address(0), "blank host"); 45 | _rewardTokenAddress = IFarmMainGen1(_farmMainContract = msg.sender)._rewardTokenAddress(); 46 | _byMint = byMint; 47 | _treasury = treasury != address(0) ? treasury : host; 48 | } 49 | 50 | function data() view public virtual override returns(address farmMainContract, bool byMint, address host, address treasury, address rewardTokenAddress) { 51 | return (_farmMainContract, _byMint, _host, _treasury, _rewardTokenAddress); 52 | } 53 | 54 | /** @dev method used to update the extension host. 55 | * @param host new host address. 56 | */ 57 | function setHost(address host) public virtual override hostOnly { 58 | _host = host; 59 | } 60 | 61 | /** @dev method used to update the extension treasury. 62 | * @param treasury new treasury address. 63 | */ 64 | function setTreasury(address treasury) public virtual override hostOnly { 65 | _treasury = treasury; 66 | } 67 | 68 | /** @dev this function calls the farm main contract with the given address and sets the given farming setups. 69 | * @param farmingSetups array containing all the farming setups. 70 | */ 71 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) public virtual override hostOnly { 72 | IFarmMainGen1(_farmMainContract).setFarmingSetups(farmingSetups); 73 | } 74 | 75 | /** @dev transfers the input amount to the caller farming contract. 76 | * @param amount amount of erc20 to transfer or mint. 77 | */ 78 | function transferTo(uint256 amount) public virtual override farmMainOnly { 79 | if(_rewardTokenAddress != address(0)) { 80 | return _byMint ? _mintAndTransfer(_rewardTokenAddress, _farmMainContract, amount) : _safeTransfer(_rewardTokenAddress, _farmMainContract, amount); 81 | } 82 | (bool result, ) = _farmMainContract.call{value:amount}(""); 83 | require(result, "ETH transfer failed."); 84 | } 85 | 86 | /** @dev transfers the input amount from the caller farming contract to the extension. 87 | * @param amount amount of erc20 to transfer back or burn. 88 | */ 89 | function backToYou(uint256 amount) payable public virtual override farmMainOnly { 90 | if(_rewardTokenAddress != address(0)) { 91 | _safeTransferFrom(_rewardTokenAddress, msg.sender, _byMint ? address(this) : _treasury, amount); 92 | if(_byMint) { 93 | _burn(_rewardTokenAddress, amount); 94 | } 95 | } else { 96 | require(msg.value == amount, "invalid sent amount"); 97 | if(_treasury != address(this)) { 98 | (bool result, ) = _treasury.call{value:amount}(""); 99 | require(result, "ETH transfer failed."); 100 | } 101 | } 102 | } 103 | 104 | /** INTERNAL METHODS */ 105 | 106 | function _mintAndTransfer(address erc20TokenAddress, address recipient, uint256 value) internal virtual { 107 | IERC20Mintable(erc20TokenAddress).mint(recipient, value); 108 | } 109 | 110 | function _burn(address erc20TokenAddress, uint256 value) internal virtual { 111 | IERC20Mintable(erc20TokenAddress).burn(msg.sender, value); 112 | } 113 | 114 | /** @dev function used to safely approve ERC20 transfers. 115 | * @param erc20TokenAddress address of the token to approve. 116 | * @param to receiver of the approval. 117 | * @param value amount to approve for. 118 | */ 119 | function _safeApprove(address erc20TokenAddress, address to, uint256 value) internal virtual { 120 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, to, value)); 121 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); 122 | } 123 | 124 | /** @dev function used to safe transfer ERC20 tokens. 125 | * @param erc20TokenAddress address of the token to transfer. 126 | * @param to receiver of the tokens. 127 | * @param value amount of tokens to transfer. 128 | */ 129 | function _safeTransfer(address erc20TokenAddress, address to, uint256 value) internal virtual { 130 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); 131 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); 132 | } 133 | 134 | /** @dev this function safely transfers the given ERC20 value from an address to another. 135 | * @param erc20TokenAddress erc20 token address. 136 | * @param from address from. 137 | * @param to address to. 138 | * @param value amount to transfer. 139 | */ 140 | function _safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal virtual { 141 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); 142 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); 143 | } 144 | 145 | /** @dev calls the contract at the given location using the given payload and returns the returnData. 146 | * @param location location to call. 147 | * @param payload call payload. 148 | * @return returnData call return data. 149 | */ 150 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 151 | assembly { 152 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 153 | let size := returndatasize() 154 | returnData := mload(0x40) 155 | mstore(returnData, size) 156 | let returnDataPayloadStart := add(returnData, 0x20) 157 | returndatacopy(returnDataPayloadStart, 0, size) 158 | mstore(0x40, add(returnDataPayloadStart, size)) 159 | switch result case 0 {revert(returnDataPayloadStart, size)} 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /contracts/farming/FarmFactory.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | import "./util/DFOHub.sol"; 5 | import "./IFarmFactory.sol"; 6 | 7 | contract FarmFactory is IFarmFactory { 8 | 9 | // farm contract implementation address 10 | address public farmMainImplAddress; 11 | // farming default extension 12 | address public override farmDefaultExtension; 13 | // double proxy address of the linked DFO 14 | address public _doubleProxy; 15 | // linked DFO exit fee 16 | uint256 private _feePercentage; 17 | // collection uri 18 | string public farmTokenCollectionURI; 19 | // farm token uri 20 | string public farmTokenURI; 21 | 22 | // event that tracks farm main contracts deployed 23 | event FarmMainDeployed(address indexed farmMainAddress, address indexed sender, bytes initResultData); 24 | // event that tracks logic contract address change 25 | event FarmMainLogicSet(address indexed newAddress); 26 | // event that tracks default extension contract address change 27 | event FarmDefaultExtensionSet(address indexed newAddress); 28 | // event that tracks wallet changes 29 | event FeePercentageSet(uint256 newFeePercentage); 30 | 31 | constructor(address doubleProxy, address _farmMainImplAddress, address _farmDefaultExtension, uint256 feePercentage, string memory farmTokenCollectionUri, string memory farmTokenUri) { 32 | _doubleProxy = doubleProxy; 33 | farmTokenCollectionURI = farmTokenCollectionUri; 34 | farmTokenURI = farmTokenUri; 35 | emit FarmMainLogicSet(farmMainImplAddress = _farmMainImplAddress); 36 | emit FarmDefaultExtensionSet(farmDefaultExtension = _farmDefaultExtension); 37 | emit FeePercentageSet(_feePercentage = feePercentage); 38 | } 39 | 40 | /** PUBLIC METHODS */ 41 | 42 | function feePercentageInfo() public override view returns (uint256, address) { 43 | return (_feePercentage, IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDWalletAddress()); 44 | } 45 | 46 | /** @dev allows the DFO to update the double proxy address. 47 | * @param newDoubleProxy new double proxy address. 48 | */ 49 | function setDoubleProxy(address newDoubleProxy) public onlyDFO { 50 | _doubleProxy = newDoubleProxy; 51 | } 52 | 53 | /** @dev change the fee percentage 54 | * @param feePercentage new fee percentage. 55 | */ 56 | function updateFeePercentage(uint256 feePercentage) public onlyDFO { 57 | emit FeePercentageSet(_feePercentage = feePercentage); 58 | } 59 | 60 | /** @dev allows the factory owner to update the logic contract address. 61 | * @param _implAddress new farm logic implementation address. 62 | */ 63 | function updateLogicAddress(address _implAddress) public onlyDFO { 64 | emit FarmMainLogicSet(farmMainImplAddress = _implAddress); 65 | } 66 | 67 | /** @dev allows the factory owner to update the default extension contract address. 68 | * @param _farmDefaultExtensionAddress new farm extension address. 69 | */ 70 | function updateDefaultExtensionAddress(address _farmDefaultExtensionAddress) public onlyDFO { 71 | emit FarmDefaultExtensionSet(farmDefaultExtension = _farmDefaultExtensionAddress); 72 | } 73 | 74 | /** @dev allows the factory owner to update the farm token collection uri. 75 | * @param farmTokenCollectionUri new farm token collection uri. 76 | */ 77 | function updateFarmTokenCollectionURI(string memory farmTokenCollectionUri) public onlyDFO { 78 | farmTokenCollectionURI = farmTokenCollectionUri; 79 | } 80 | 81 | /** @dev allows the factory owner to update the farm token uri. 82 | * @param farmTokenUri new farm token collection uri. 83 | */ 84 | function updateFarmTokenURI(string memory farmTokenUri) public onlyDFO { 85 | farmTokenURI = farmTokenUri; 86 | } 87 | 88 | /** @dev returns the farm token collection uri. 89 | * @return farm token collection uri. 90 | */ 91 | function getFarmTokenCollectionURI() public override view returns (string memory) { 92 | return farmTokenCollectionURI; 93 | } 94 | 95 | /** @dev returns the farm token uri. 96 | * @return farm token uri. 97 | */ 98 | function getFarmTokenURI() public override view returns (string memory) { 99 | return farmTokenURI; 100 | } 101 | 102 | /** @dev utlity method to clone default extension 103 | * @return clonedExtension the address of the actually-cloned farming extension 104 | */ 105 | function cloneFarmDefaultExtension() public override returns(address clonedExtension) { 106 | emit ExtensionCloned(clonedExtension = _clone(farmDefaultExtension)); 107 | } 108 | 109 | /** @dev this function deploys a new Farming contract and calls the encoded function passed as data. 110 | * @param data encoded initialize function for the farming contract (check Farming contract code). 111 | * @return contractAddress new farming contract address. 112 | * @return initResultData new farming contract call result. 113 | */ 114 | function deploy(bytes memory data) public returns (address contractAddress, bytes memory initResultData) { 115 | initResultData = _call(contractAddress = _clone(farmMainImplAddress), data); 116 | emit FarmMainDeployed(contractAddress, msg.sender, initResultData); 117 | } 118 | 119 | /** PRIVATE METHODS */ 120 | 121 | /** @dev clones the input contract address and returns the copied contract address. 122 | * @param original address of the original contract. 123 | * @return copy copied contract address. 124 | */ 125 | function _clone(address original) private returns (address copy) { 126 | assembly { 127 | mstore( 128 | 0, 129 | or( 130 | 0x5880730000000000000000000000000000000000000000803b80938091923cF3, 131 | mul(original, 0x1000000000000000000) 132 | ) 133 | ) 134 | copy := create(0, 0, 32) 135 | switch extcodesize(copy) 136 | case 0 { 137 | invalid() 138 | } 139 | } 140 | } 141 | 142 | /** @dev calls the contract at the given location using the given payload and returns the returnData. 143 | * @param location location to call. 144 | * @param payload call payload. 145 | * @return returnData call return data. 146 | */ 147 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 148 | assembly { 149 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 150 | let size := returndatasize() 151 | returnData := mload(0x40) 152 | mstore(returnData, size) 153 | let returnDataPayloadStart := add(returnData, 0x20) 154 | returndatacopy(returnDataPayloadStart, 0, size) 155 | mstore(0x40, add(returnDataPayloadStart, size)) 156 | switch result case 0 {revert(returnDataPayloadStart, size)} 157 | } 158 | } 159 | 160 | /** @dev onlyDFO modifier used to check for unauthorized accesses. */ 161 | modifier onlyDFO() { 162 | require(IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(msg.sender), "Unauthorized."); 163 | _; 164 | } 165 | } -------------------------------------------------------------------------------- /contracts/farming/IFarmExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FarmData.sol"; 6 | 7 | interface IFarmExtension { 8 | 9 | function init(bool byMint, address host, address treasury) external; 10 | 11 | function setHost(address host) external; 12 | function setTreasury(address treasury) external; 13 | 14 | function data() external view returns(address farmMainContract, bool byMint, address host, address treasury, address rewardTokenAddress); 15 | 16 | function transferTo(uint256 amount) external; 17 | function backToYou(uint256 amount) external payable; 18 | 19 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) external; 20 | } -------------------------------------------------------------------------------- /contracts/farming/IFarmExtensionGen1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FarmDataGen1.sol"; 6 | 7 | interface IFarmExtensionGen1 { 8 | 9 | function init(bool byMint, address host, address treasury) external; 10 | 11 | function setHost(address host) external; 12 | function setTreasury(address treasury) external; 13 | 14 | function data() external view returns(address farmMainContract, bool byMint, address host, address treasury, address rewardTokenAddress); 15 | 16 | function transferTo(uint256 amount) external; 17 | function backToYou(uint256 amount) external payable; 18 | 19 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) external; 20 | 21 | } -------------------------------------------------------------------------------- /contracts/farming/IFarmExtensionRegular.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FarmDataRegular.sol"; 6 | 7 | interface IFarmExtensionRegular { 8 | 9 | function init(bool byMint, address host, address treasury) external; 10 | 11 | function setHost(address host) external; 12 | function setTreasury(address treasury) external; 13 | 14 | function data() external view returns(address farmMainContract, bool byMint, address host, address treasury, address rewardTokenAddress); 15 | 16 | function transferTo(uint256 amount) external; 17 | function backToYou(uint256 amount) external payable; 18 | 19 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) external; 20 | } -------------------------------------------------------------------------------- /contracts/farming/IFarmFactory.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | interface IFarmFactory { 5 | 6 | event ExtensionCloned(address indexed); 7 | 8 | function feePercentageInfo() external view returns (uint256, address); 9 | function farmDefaultExtension() external view returns(address); 10 | function cloneFarmDefaultExtension() external returns(address); 11 | function getFarmTokenCollectionURI() external view returns (string memory); 12 | function getFarmTokenURI() external view returns (string memory); 13 | } -------------------------------------------------------------------------------- /contracts/farming/IFarmMain.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FarmData.sol"; 6 | 7 | interface IFarmMain { 8 | 9 | function ONE_HUNDRED() external view returns(uint256); 10 | function _rewardTokenAddress() external view returns(address); 11 | function position(uint256 positionId) external view returns (FarmingPosition memory); 12 | function setups() external view returns (FarmingSetup[] memory); 13 | function setup(uint256 setupIndex) external view returns (FarmingSetup memory, FarmingSetupInfo memory); 14 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) external; 15 | function openPosition(FarmingPositionRequest calldata request) external payable returns(uint256 positionId); 16 | function addLiquidity(uint256 positionId, FarmingPositionRequest calldata request) external payable; 17 | } -------------------------------------------------------------------------------- /contracts/farming/IFarmMainGen1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FarmDataGen1.sol"; 6 | 7 | interface IFarmMainGen1 { 8 | 9 | function ONE_HUNDRED() external view returns(uint256); 10 | function _rewardTokenAddress() external view returns(address); 11 | function position(uint256 positionId) external view returns (FarmingPosition memory); 12 | function setups() external view returns (FarmingSetup[] memory); 13 | function setup(uint256 setupIndex) external view returns (FarmingSetup memory, FarmingSetupInfo memory); 14 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) external; 15 | function openPosition(FarmingPositionRequest calldata request) external payable returns(uint256 positionId); 16 | function addLiquidity(uint256 positionId, FarmingPositionRequest calldata request) external payable; 17 | } -------------------------------------------------------------------------------- /contracts/farming/IFarmMainRegular.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FarmDataRegular.sol"; 6 | 7 | interface IFarmMainRegular { 8 | 9 | function ONE_HUNDRED() external view returns(uint256); 10 | function _rewardTokenAddress() external view returns(address); 11 | function position(uint256 positionId) external view returns (FarmingPosition memory); 12 | function setups() external view returns (FarmingSetup[] memory); 13 | function setup(uint256 setupIndex) external view returns (FarmingSetup memory, FarmingSetupInfo memory); 14 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) external; 15 | function openPosition(FarmingPositionRequest calldata request) external payable returns(uint256 positionId); 16 | function addLiquidity(uint256 positionId, FarmingPositionRequest calldata request) external payable; 17 | } -------------------------------------------------------------------------------- /contracts/farming/dfo/DFOBasedFarmExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../IFarmExtension.sol"; 6 | import "../IFarmMain.sol"; 7 | import "../util/IERC20.sol"; 8 | import "../util/DFOHub.sol"; 9 | 10 | contract DFOBasedFarmExtension is IFarmExtension { 11 | 12 | string private constant FUNCTIONALITY_NAME = "manageFarming"; 13 | 14 | // wallet who has control on the extension 15 | address internal _doubleProxy; 16 | 17 | // mapping that contains all the farming contract linked to this extension 18 | address internal _farmingContract; 19 | 20 | // the reward token address linked to this farming contract 21 | address internal _rewardTokenAddress; 22 | 23 | // whether the token is by mint or by reserve 24 | bool internal _byMint; 25 | 26 | /** MODIFIERS */ 27 | 28 | /** @dev farmingOnly modifier used to check for unauthorized transfers. */ 29 | modifier farmingOnly() { 30 | require(msg.sender == _farmingContract, "Unauthorized"); 31 | _; 32 | } 33 | 34 | /** @dev hostOnly modifier used to check for unauthorized edits. */ 35 | modifier hostOnly() { 36 | require(_isFromDFO(msg.sender), "Unauthorized"); 37 | _; 38 | } 39 | 40 | /** PUBLIC METHODS */ 41 | 42 | function init(bool byMint, address host, address) public virtual override { 43 | require(_farmingContract == address(0), "Already init"); 44 | require((_doubleProxy = host) != address(0), "blank host"); 45 | _rewardTokenAddress = IFarmMain(_farmingContract = msg.sender)._rewardTokenAddress(); 46 | _byMint = byMint; 47 | } 48 | 49 | /** @dev allows the DFO to update the double proxy address. 50 | * @param newDoubleProxy new double proxy address. 51 | */ 52 | function setHost(address newDoubleProxy) public virtual override hostOnly { 53 | _doubleProxy = newDoubleProxy; 54 | } 55 | 56 | /** @dev method used to update the extension treasury. 57 | */ 58 | function setTreasury(address) public virtual override hostOnly { 59 | revert("Impossibru!"); 60 | } 61 | 62 | function data() view public virtual override returns(address farmingContract, bool byMint, address host, address treasury, address rewardTokenAddress) { 63 | return (_farmingContract, _byMint, _doubleProxy, IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDWalletAddress(), _rewardTokenAddress); 64 | } 65 | 66 | /** @dev transfers the input amount to the caller farming contract. 67 | * @param amount amount of erc20 to transfer or mint. 68 | */ 69 | function transferTo(uint256 amount) override public farmingOnly { 70 | IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).submit(FUNCTIONALITY_NAME, abi.encode(address(0), 0, true, _rewardTokenAddress, _farmingContract, amount, _byMint)); 71 | } 72 | 73 | /** @dev transfers the input amount from the caller farming contract to the extension. 74 | * @param amount amount of erc20 to transfer back or burn. 75 | */ 76 | function backToYou(uint256 amount) override payable public farmingOnly { 77 | if(_rewardTokenAddress != address(0)) { 78 | _safeTransferFrom(_rewardTokenAddress, msg.sender, address(this), amount); 79 | _safeApprove(_rewardTokenAddress, _getFunctionalityAddress(), amount); 80 | IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).submit(FUNCTIONALITY_NAME, abi.encode(address(0), 0, false, _rewardTokenAddress, msg.sender, amount, _byMint)); 81 | } else { 82 | IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).submit{value : amount}(FUNCTIONALITY_NAME, abi.encode(address(0), 0, false, _rewardTokenAddress, msg.sender, amount, _byMint)); 83 | } 84 | } 85 | 86 | /** @dev this function calls the farming contract with the given address and sets the given farming setups. 87 | * @param farmingSetups array containing all the farming setups. 88 | */ 89 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) public override hostOnly { 90 | IFarmMain(_farmingContract).setFarmingSetups(farmingSetups); 91 | } 92 | 93 | /** PRIVATE METHODS */ 94 | 95 | /** @dev this function returns the address of the functionality with the FUNCTIONALITY_NAME. 96 | * @return functionalityAddress functionality FUNCTIONALITY_NAME address. 97 | */ 98 | function _getFunctionalityAddress() private view returns(address functionalityAddress) { 99 | (functionalityAddress,,,,) = IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).getFunctionalityData(FUNCTIONALITY_NAME); 100 | } 101 | 102 | /** @dev this function returns the address of the wallet of the linked DFO. 103 | * @return linked DFO wallet address. 104 | */ 105 | function _getDFOWallet() private view returns(address) { 106 | return IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDWalletAddress(); 107 | } 108 | 109 | /** @dev this function returns true if the sender is an authorized DFO functionality, false otherwise. 110 | * @param sender address of the caller. 111 | * @return true if the call is from a DFO, false otherwise. 112 | */ 113 | function _isFromDFO(address sender) private view returns(bool) { 114 | return IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(sender); 115 | } 116 | 117 | /** @dev function used to safely approve ERC20 transfers. 118 | * @param erc20TokenAddress address of the token to approve. 119 | * @param to receiver of the approval. 120 | * @param value amount to approve for. 121 | */ 122 | function _safeApprove(address erc20TokenAddress, address to, uint256 value) internal virtual { 123 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, to, value)); 124 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); 125 | } 126 | 127 | /** @dev this function safely transfers the given ERC20 value from an address to another. 128 | * @param erc20TokenAddress erc20 token address. 129 | * @param from address from. 130 | * @param to address to. 131 | * @param value amount to transfer. 132 | */ 133 | function _safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) private { 134 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); 135 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); 136 | } 137 | 138 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 139 | assembly { 140 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 141 | let size := returndatasize() 142 | returnData := mload(0x40) 143 | mstore(returnData, size) 144 | let returnDataPayloadStart := add(returnData, 0x20) 145 | returndatacopy(returnDataPayloadStart, 0, size) 146 | mstore(0x40, add(returnDataPayloadStart, size)) 147 | switch result case 0 {revert(returnDataPayloadStart, size)} 148 | } 149 | } 150 | } -------------------------------------------------------------------------------- /contracts/farming/dfo/DFOBasedFarmExtensionFactory.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | import "../util/DFOHub.sol"; 5 | 6 | contract DFOBasedFarmExtensionFactory { 7 | 8 | address public doubleProxy; 9 | 10 | address public model; 11 | 12 | event ExtensionCloned(address indexed extensionAddress, address indexed sender); 13 | 14 | constructor(address doubleProxyAddress, address modelAddress) { 15 | doubleProxy = doubleProxyAddress; 16 | model = modelAddress; 17 | } 18 | 19 | function setDoubleProxy(address doubleProxyAddress) public onlyDFO { 20 | doubleProxy = doubleProxyAddress; 21 | } 22 | 23 | function setModel(address modelAddress) public onlyDFO { 24 | model = modelAddress; 25 | } 26 | 27 | function cloneModel() public returns(address clonedExtension) { 28 | emit ExtensionCloned(clonedExtension = _clone(model), msg.sender); 29 | } 30 | 31 | function _clone(address original) private returns (address copy) { 32 | assembly { 33 | mstore( 34 | 0, 35 | or( 36 | 0x5880730000000000000000000000000000000000000000803b80938091923cF3, 37 | mul(original, 0x1000000000000000000) 38 | ) 39 | ) 40 | copy := create(0, 0, 32) 41 | switch extcodesize(copy) 42 | case 0 { 43 | invalid() 44 | } 45 | } 46 | } 47 | 48 | modifier onlyDFO() { 49 | require(IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(msg.sender), "Unauthorized."); 50 | _; 51 | } 52 | } -------------------------------------------------------------------------------- /contracts/farming/dfo/DFOBasedFarmExtensionGen1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../IFarmExtensionGen1.sol"; 6 | import "../IFarmMainGen1.sol"; 7 | import "../util/IERC20.sol"; 8 | import "../util/DFOHub.sol"; 9 | 10 | contract DFOBasedFarmExtension is IFarmExtensionGen1 { 11 | 12 | string private constant FUNCTIONALITY_NAME = "manageFarming"; 13 | 14 | // wallet who has control on the extension 15 | address internal _doubleProxy; 16 | 17 | // mapping that contains all the farming contract linked to this extension 18 | address internal _farmingContract; 19 | 20 | // the reward token address linked to this farming contract 21 | address internal _rewardTokenAddress; 22 | 23 | // whether the token is by mint or by reserve 24 | bool internal _byMint; 25 | 26 | /** MODIFIERS */ 27 | 28 | /** @dev farmingOnly modifier used to check for unauthorized transfers. */ 29 | modifier farmingOnly() { 30 | require(msg.sender == _farmingContract, "Unauthorized"); 31 | _; 32 | } 33 | 34 | /** @dev hostOnly modifier used to check for unauthorized edits. */ 35 | modifier hostOnly() { 36 | require(_isFromDFO(msg.sender), "Unauthorized"); 37 | _; 38 | } 39 | 40 | /** PUBLIC METHODS */ 41 | 42 | function init(bool byMint, address host, address) public virtual override { 43 | require(_farmingContract == address(0), "Already init"); 44 | require((_doubleProxy = host) != address(0), "blank host"); 45 | _rewardTokenAddress = IFarmMainGen1(_farmingContract = msg.sender)._rewardTokenAddress(); 46 | _byMint = byMint; 47 | } 48 | 49 | /** @dev allows the DFO to update the double proxy address. 50 | * @param newDoubleProxy new double proxy address. 51 | */ 52 | function setHost(address newDoubleProxy) public virtual override hostOnly { 53 | _doubleProxy = newDoubleProxy; 54 | } 55 | 56 | /** @dev method used to update the extension treasury. 57 | */ 58 | function setTreasury(address) public virtual override hostOnly { 59 | revert("Impossibru!"); 60 | } 61 | 62 | function data() view public virtual override returns(address farmingContract, bool byMint, address host, address treasury, address rewardTokenAddress) { 63 | return (_farmingContract, _byMint, _doubleProxy, IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDWalletAddress(), _rewardTokenAddress); 64 | } 65 | 66 | /** @dev transfers the input amount to the caller farming contract. 67 | * @param amount amount of erc20 to transfer or mint. 68 | */ 69 | function transferTo(uint256 amount) override public farmingOnly { 70 | IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).submit(FUNCTIONALITY_NAME, abi.encode(address(0), 0, true, _rewardTokenAddress, _farmingContract, amount, _byMint)); 71 | } 72 | 73 | /** @dev transfers the input amount from the caller farming contract to the extension. 74 | * @param amount amount of erc20 to transfer back or burn. 75 | */ 76 | function backToYou(uint256 amount) override payable public farmingOnly { 77 | if(_rewardTokenAddress != address(0)) { 78 | _safeTransferFrom(_rewardTokenAddress, msg.sender, address(this), amount); 79 | _safeApprove(_rewardTokenAddress, _getFunctionalityAddress(), amount); 80 | IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).submit(FUNCTIONALITY_NAME, abi.encode(address(0), 0, false, _rewardTokenAddress, msg.sender, amount, _byMint)); 81 | } else { 82 | IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).submit{value : amount}(FUNCTIONALITY_NAME, abi.encode(address(0), 0, false, _rewardTokenAddress, msg.sender, amount, _byMint)); 83 | } 84 | } 85 | 86 | /** @dev this function calls the farming contract with the given address and sets the given farming setups. 87 | * @param farmingSetups array containing all the farming setups. 88 | */ 89 | function setFarmingSetups(FarmingSetupConfiguration[] memory farmingSetups) public override hostOnly { 90 | IFarmMainGen1(_farmingContract).setFarmingSetups(farmingSetups); 91 | } 92 | 93 | /** PRIVATE METHODS */ 94 | 95 | /** @dev this function returns the address of the functionality with the FUNCTIONALITY_NAME. 96 | * @return functionalityAddress functionality FUNCTIONALITY_NAME address. 97 | */ 98 | function _getFunctionalityAddress() private view returns(address functionalityAddress) { 99 | (functionalityAddress,,,,) = IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).getFunctionalityData(FUNCTIONALITY_NAME); 100 | } 101 | 102 | /** @dev this function returns the address of the wallet of the linked DFO. 103 | * @return linked DFO wallet address. 104 | */ 105 | function _getDFOWallet() private view returns(address) { 106 | return IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDWalletAddress(); 107 | } 108 | 109 | /** @dev this function returns true if the sender is an authorized DFO functionality, false otherwise. 110 | * @param sender address of the caller. 111 | * @return true if the call is from a DFO, false otherwise. 112 | */ 113 | function _isFromDFO(address sender) private view returns(bool) { 114 | return IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(sender); 115 | } 116 | 117 | /** @dev function used to safely approve ERC20 transfers. 118 | * @param erc20TokenAddress address of the token to approve. 119 | * @param to receiver of the approval. 120 | * @param value amount to approve for. 121 | */ 122 | function _safeApprove(address erc20TokenAddress, address to, uint256 value) internal virtual { 123 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, to, value)); 124 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); 125 | } 126 | 127 | /** @dev this function safely transfers the given ERC20 value from an address to another. 128 | * @param erc20TokenAddress erc20 token address. 129 | * @param from address from. 130 | * @param to address to. 131 | * @param value amount to transfer. 132 | */ 133 | function _safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) private { 134 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); 135 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); 136 | } 137 | 138 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 139 | assembly { 140 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 141 | let size := returndatasize() 142 | returnData := mload(0x40) 143 | mstore(returnData, size) 144 | let returnDataPayloadStart := add(returnData, 0x20) 145 | returndatacopy(returnDataPayloadStart, 0, size) 146 | mstore(0x40, add(returnDataPayloadStart, size)) 147 | switch result case 0 {revert(returnDataPayloadStart, size)} 148 | } 149 | } 150 | } -------------------------------------------------------------------------------- /contracts/farming/dfo/ManageFarmingFunctionality.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | contract ProposalCode { 6 | 7 | string private _metadataLink; 8 | 9 | constructor(string memory metadataLink) { 10 | _metadataLink = metadataLink; 11 | } 12 | 13 | function getMetadataLink() public view returns(string memory) { 14 | return _metadataLink; 15 | } 16 | 17 | function onStart(address, address) public { 18 | IMVDProxy proxy = IMVDProxy(msg.sender); 19 | IStateHolder stateHolder = IStateHolder(proxy.getStateHolderAddress()); 20 | stateHolder.setBool(_toStateHolderKey("farming.authorized", _toString({0})), true); 21 | } 22 | 23 | function onStop(address) public { 24 | } 25 | 26 | function manageFarming(address sender, uint256, bool transfer, address erc20TokenAddress, address to, uint256 value, bool byMint) public { 27 | IMVDProxy proxy = IMVDProxy(msg.sender); 28 | IStateHolder stateHolder = IStateHolder(proxy.getStateHolderAddress()); 29 | require(stateHolder.getBool(_toStateHolderKey("farming.authorized", _toString(sender))), "Unauthorized action"); 30 | IERC20 token = IERC20(erc20TokenAddress); 31 | if(transfer) { 32 | if(byMint) { 33 | uint256 lastAmount = token.balanceOf(msg.sender); 34 | token.mint(value); 35 | proxy.flushToWallet(erc20TokenAddress, false, 0); 36 | if(lastAmount > 0) { 37 | proxy.transfer(msg.sender, lastAmount, address(token)); 38 | } 39 | } 40 | proxy.transfer(to, value, erc20TokenAddress); 41 | } else { 42 | if(erc20TokenAddress == address(0)) { 43 | return; 44 | } 45 | token.transferFrom(sender, byMint ? address(this) : proxy.getMVDWalletAddress(), value); 46 | if(byMint) { 47 | token.burn(value); 48 | } 49 | } 50 | } 51 | 52 | function _toStateHolderKey(string memory a, string memory b) private pure returns(string memory) { 53 | return _toLowerCase(string(abi.encodePacked(a, ".", b))); 54 | } 55 | 56 | function _toString(address _addr) private pure returns(string memory) { 57 | bytes32 value = bytes32(uint256(_addr)); 58 | bytes memory alphabet = "0123456789abcdef"; 59 | 60 | bytes memory str = new bytes(42); 61 | str[0] = '0'; 62 | str[1] = 'x'; 63 | for (uint i = 0; i < 20; i++) { 64 | str[2+i*2] = alphabet[uint(uint8(value[i + 12] >> 4))]; 65 | str[3+i*2] = alphabet[uint(uint8(value[i + 12] & 0x0f))]; 66 | } 67 | return string(str); 68 | } 69 | 70 | function _toLowerCase(string memory str) private pure returns(string memory) { 71 | bytes memory bStr = bytes(str); 72 | for (uint i = 0; i < bStr.length; i++) { 73 | bStr[i] = bStr[i] >= 0x41 && bStr[i] <= 0x5A ? bytes1(uint8(bStr[i]) + 0x20) : bStr[i]; 74 | } 75 | return string(bStr); 76 | } 77 | } 78 | 79 | interface IMVDProxy { 80 | function getStateHolderAddress() external view returns(address); 81 | function getMVDWalletAddress() external view returns(address); 82 | function transfer(address receiver, uint256 value, address token) external; 83 | function flushToWallet(address tokenAddress, bool is721, uint256 tokenId) external; 84 | } 85 | 86 | interface IStateHolder { 87 | function setUint256(string calldata name, uint256 value) external returns(uint256); 88 | function getUint256(string calldata name) external view returns(uint256); 89 | function getAddress(string calldata name) external view returns(address); 90 | function setAddress(string calldata varName, address val) external returns (address); 91 | function getBool(string calldata varName) external view returns (bool); 92 | function setBool(string calldata varName, bool val) external returns(bool); 93 | function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal); 94 | } 95 | 96 | interface IERC20 { 97 | function totalSupply() external view returns (uint256); 98 | function balanceOf(address account) external view returns (uint256); 99 | function transfer(address recipient, uint256 amount) external returns (bool); 100 | function allowance(address owner, address spender) external view returns (uint256); 101 | function approve(address spender, uint256 amount) external returns (bool); 102 | function safeApprove(address spender, uint256 amount) external; 103 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 104 | function decimals() external view returns (uint8); 105 | function mint(uint256 amount) external; 106 | function burn(uint256 amount) external; 107 | } -------------------------------------------------------------------------------- /contracts/farming/util/DFOHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IDoubleProxy { 6 | function proxy() external view returns (address); 7 | } 8 | 9 | interface IMVDProxy { 10 | function getMVDFunctionalitiesManagerAddress() external view returns(address); 11 | function getMVDWalletAddress() external view returns (address); 12 | function getStateHolderAddress() external view returns(address); 13 | function submit(string calldata codeName, bytes calldata data) external payable returns(bytes memory returnData); 14 | } 15 | 16 | interface IMVDFunctionalitiesManager { 17 | function getFunctionalityData(string calldata codeName) external view returns(address, uint256, string memory, address, uint256); 18 | function isAuthorizedFunctionality(address functionality) external view returns(bool); 19 | } 20 | 21 | interface IStateHolder { 22 | function getUint256(string calldata name) external view returns(uint256); 23 | function getAddress(string calldata name) external view returns(address); 24 | function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal); 25 | } -------------------------------------------------------------------------------- /contracts/farming/util/ERC1155Receiver.sol: -------------------------------------------------------------------------------- 1 | // File: contracts/usd-v2/util/ERC1155Receiver.sol 2 | 3 | // SPDX-License-Identifier: MIT 4 | 5 | pragma solidity >=0.7.0; 6 | 7 | abstract contract ERC1155Receiver { 8 | bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; 9 | 10 | mapping(bytes4 => bool) private _supportedInterfaces; 11 | 12 | constructor() { 13 | _registerInterface(_INTERFACE_ID_ERC165); 14 | _registerInterface( 15 | ERC1155Receiver(0).onERC1155Received.selector ^ 16 | ERC1155Receiver(0).onERC1155BatchReceived.selector 17 | ); 18 | } 19 | 20 | function supportsInterface(bytes4 interfaceId) public view returns (bool) { 21 | return _supportedInterfaces[interfaceId]; 22 | } 23 | 24 | function _registerInterface(bytes4 interfaceId) internal virtual { 25 | require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); 26 | _supportedInterfaces[interfaceId] = true; 27 | } 28 | 29 | function onERC1155Received( 30 | address operator, 31 | address from, 32 | uint256 id, 33 | uint256 value, 34 | bytes calldata data 35 | ) 36 | external 37 | virtual 38 | returns(bytes4); 39 | 40 | function onERC1155BatchReceived( 41 | address operator, 42 | address from, 43 | uint256[] calldata ids, 44 | uint256[] calldata values, 45 | bytes calldata data 46 | ) 47 | external 48 | virtual 49 | returns(bytes4); 50 | } -------------------------------------------------------------------------------- /contracts/farming/util/IERC1155.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC1155 { 6 | 7 | event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); 8 | 9 | event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); 10 | 11 | event ApprovalForAll(address indexed account, address indexed operator, bool approved); 12 | 13 | event URI(string value, uint256 indexed id); 14 | 15 | function balanceOf(address account, uint256 id) external view returns (uint256); 16 | 17 | function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); 18 | 19 | function setApprovalForAll(address operator, bool approved) external; 20 | 21 | function isApprovedForAll(address account, address operator) external view returns (bool); 22 | 23 | function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; 24 | 25 | function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/farming/util/IERC165.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: BSD-2 2 | pragma solidity >=0.7.0; 3 | 4 | /** 5 | * @dev Interface of the ERC165 standard, as defined in the 6 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 7 | * 8 | * Implementers can declare support of contract interfaces, which can then be 9 | * queried by others ({ERC165Checker}). 10 | * 11 | * For an implementation, see {ERC165}. 12 | */ 13 | interface IERC165 { 14 | /** 15 | * @dev Returns true if this contract implements the interface defined by 16 | * `interfaceId`. See the corresponding 17 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 18 | * to learn more about how these ids are created. 19 | * 20 | * This function call must use less than 30 000 gas. 21 | */ 22 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 23 | } -------------------------------------------------------------------------------- /contracts/farming/util/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC20 { 6 | 7 | function totalSupply() external view returns (uint256); 8 | 9 | function balanceOf(address account) external view returns (uint256); 10 | 11 | function transfer(address recipient, uint256 amount) external returns (bool); 12 | 13 | function allowance(address owner, address spender) external view returns (uint256); 14 | 15 | function approve(address spender, uint256 amount) external returns (bool); 16 | 17 | function safeApprove(address spender, uint256 amount) external; 18 | 19 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 20 | 21 | function decimals() external view returns (uint8); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/farming/util/IERC20Mintable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC20Mintable { 6 | function mint(address wallet, uint256 amount) external returns (bool); 7 | function burn(address wallet, uint256 amount) external returns (bool); 8 | } 9 | -------------------------------------------------------------------------------- /contracts/farming/util/IEthItem.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IERC1155.sol"; 6 | import "./IEthItemInteroperableInterface.sol"; 7 | 8 | interface IEthItem is IERC1155 { 9 | 10 | function name() external view returns (string memory); 11 | 12 | function symbol() external view returns (string memory); 13 | 14 | function totalSupply(uint256 objectId) external view returns (uint256); 15 | 16 | function name(uint256 objectId) external view returns (string memory); 17 | 18 | function symbol(uint256 objectId) external view returns (string memory); 19 | 20 | function decimals(uint256 objectId) external view returns (uint256); 21 | 22 | function uri(uint256 objectId) external view returns (string memory); 23 | 24 | function mainInterfaceVersion() external pure returns(uint256 ethItemInteroperableVersion); 25 | 26 | function toInteroperableInterfaceAmount(uint256 objectId, uint256 ethItemAmount) external view returns (uint256 interoperableInterfaceAmount); 27 | 28 | function toMainInterfaceAmount(uint256 objectId, uint256 erc20WrapperAmount) external view returns (uint256 mainInterfaceAmount); 29 | 30 | function interoperableInterfaceModel() external view returns (address, uint256); 31 | 32 | function asInteroperable(uint256 objectId) external view returns (IEthItemInteroperableInterface); 33 | 34 | function emitTransferSingleEvent(address sender, address from, address to, uint256 objectId, uint256 amount) external; 35 | 36 | function mint(uint256 amount, string calldata partialUri) 37 | external 38 | returns (uint256, address); 39 | 40 | function burn( 41 | uint256 objectId, 42 | uint256 amount 43 | ) external; 44 | 45 | function burnBatch( 46 | uint256[] calldata objectIds, 47 | uint256[] calldata amounts 48 | ) external; 49 | } -------------------------------------------------------------------------------- /contracts/farming/util/IEthItemInteroperableInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IERC20.sol"; 6 | 7 | interface IEthItemInteroperableInterface is IERC20 { 8 | 9 | function mainInterface() external view returns (address); 10 | 11 | function objectId() external view returns (uint256); 12 | 13 | function mint(address owner, uint256 amount) external; 14 | 15 | function burn(address owner, uint256 amount) external; 16 | 17 | function permitNonce(address sender) external view returns(uint256); 18 | 19 | function permit(address owner, address spender, uint value, uint8 v, bytes32 r, bytes32 s) external; 20 | 21 | function interoperableInterfaceVersion() external pure returns(uint256 ethItemInteroperableInterfaceVersion); 22 | } -------------------------------------------------------------------------------- /contracts/farming/util/IEthItemOrchestrator.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IEthItemOrchestrator { 6 | function createNative(bytes calldata modelInitPayload, string calldata ens) 7 | external 8 | returns (address newNativeAddress, bytes memory modelInitCallResponse); 9 | } -------------------------------------------------------------------------------- /contracts/farming/util/INativeV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IEthItem.sol"; 6 | 7 | interface INativeV1 is IEthItem { 8 | 9 | function init(string calldata name, string calldata symbol, bool hasDecimals, string calldata collectionUri, address extensionAddress, bytes calldata extensionInitPayload) external returns(bytes memory extensionInitCallResponse); 10 | function extension() external view returns (address extensionAddress); 11 | function canMint(address operator) external view returns (bool result); 12 | function isEditable(uint256 objectId) external view returns (bool result); 13 | function releaseExtension() external; 14 | function uri() external view returns (string memory); 15 | function decimals() external view returns (uint256); 16 | function mint(uint256 amount, string calldata tokenName, string calldata tokenSymbol, string calldata objectUri, bool editable) external returns (uint256 objectId, address tokenAddress); 17 | function mint(uint256 amount, string calldata tokenName, string calldata tokenSymbol, string calldata objectUri) external returns (uint256 objectId, address tokenAddress); 18 | function mint(uint256 objectId, uint256 amount) external; 19 | function makeReadOnly(uint256 objectId) external; 20 | function setUri(string calldata newUri) external; 21 | function setUri(uint256 objectId, string calldata newUri) external; 22 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/FixedInflationData.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | struct FixedInflationEntry { 5 | string name; 6 | uint256 eventInterval; 7 | uint256 lastEvent; 8 | uint256 callerRewardPercentage; 9 | } 10 | 11 | struct FixedInflationOperation { 12 | 13 | address inputTokenAddress; 14 | uint256 inputTokenAmount; 15 | bool inputTokenAmountIsPercentage; 16 | bool inputTokenAmountIsByMint; 17 | 18 | address ammPlugin; 19 | address[] liquidityPoolAddresses; 20 | address[] swapPath; 21 | bool enterInETH; 22 | bool exitInETH; 23 | 24 | address[] receivers; 25 | uint256[] receiversPercentages; 26 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/FixedInflationExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FixedInflationData.sol"; 6 | import "./IFixedInflationExtension.sol"; 7 | import "./util/IERC20.sol"; 8 | import "./util/IERC20Mintable.sol"; 9 | import "./util/IERC20Burnable.sol"; 10 | import "./IFixedInflation.sol"; 11 | 12 | contract FixedInflationExtension is IFixedInflationExtension { 13 | 14 | address private _host; 15 | 16 | address private _fixedInflationContract; 17 | 18 | bool public override active; 19 | 20 | modifier fixedInflationOnly() { 21 | require(_fixedInflationContract == msg.sender, "Unauthorized"); 22 | _; 23 | } 24 | 25 | modifier hostOnly() { 26 | require(_host == msg.sender, "Unauthorized"); 27 | _; 28 | } 29 | 30 | receive() external payable { 31 | } 32 | 33 | function init(address host) override public virtual { 34 | require(_host == address(0), "Already init"); 35 | require((_host = host) != address(0), "blank host"); 36 | _fixedInflationContract = msg.sender; 37 | } 38 | 39 | function setHost(address host) public virtual override hostOnly { 40 | _host = host; 41 | } 42 | 43 | function data() view public override returns(address fixedInflationContract, address host) { 44 | return(_fixedInflationContract, _host); 45 | } 46 | 47 | function setActive(bool _active) public override virtual hostOnly { 48 | active = _active; 49 | } 50 | 51 | function receiveTokens(address[] memory tokenAddresses, uint256[] memory transferAmounts, uint256[] memory amountsToMint) public override fixedInflationOnly { 52 | for(uint256 i = 0; i < tokenAddresses.length; i++) { 53 | if(transferAmounts[i] > 0) { 54 | if(tokenAddresses[i] == address(0)) { 55 | (bool result,) = msg.sender.call{value:transferAmounts[i]}(""); 56 | require(result, "ETH transfer failed"); 57 | continue; 58 | } 59 | _safeTransfer(tokenAddresses[i], msg.sender, transferAmounts[i]); 60 | } 61 | if(amountsToMint[i] > 0) { 62 | _mintAndTransfer(tokenAddresses[i], msg.sender, amountsToMint[i]); 63 | } 64 | } 65 | } 66 | 67 | function setEntry(FixedInflationEntry memory newEntry, FixedInflationOperation[] memory newOperations) public override hostOnly { 68 | IFixedInflation(_fixedInflationContract).setEntry(newEntry, newOperations); 69 | } 70 | 71 | function flushBack(address[] memory tokenAddresses) public override hostOnly { 72 | IFixedInflation(_fixedInflationContract).flushBack(tokenAddresses); 73 | } 74 | 75 | function deactivationByFailure() public override fixedInflationOnly { 76 | active = false; 77 | } 78 | 79 | function burnToken(address erc20TokenAddress, uint256 value) external override fixedInflationOnly { 80 | _safeTransferFrom(erc20TokenAddress, _fixedInflationContract, address(this), value); 81 | _burn(erc20TokenAddress, value); 82 | } 83 | 84 | /** INTERNAL METHODS */ 85 | 86 | function _mintAndTransfer(address erc20TokenAddress, address recipient, uint256 value) internal virtual { 87 | IERC20Mintable(erc20TokenAddress).mint(recipient, value); 88 | } 89 | 90 | function _burn(address erc20TokenAddress, uint256 value) internal virtual { 91 | IERC20Burnable(erc20TokenAddress).burn(value); 92 | } 93 | 94 | function _safeTransfer(address erc20TokenAddress, address to, uint256 value) internal virtual { 95 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); 96 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); 97 | } 98 | 99 | function _safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal { 100 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); 101 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); 102 | } 103 | 104 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 105 | assembly { 106 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 107 | let size := returndatasize() 108 | returnData := mload(0x40) 109 | mstore(returnData, size) 110 | let returnDataPayloadStart := add(returnData, 0x20) 111 | returndatacopy(returnDataPayloadStart, 0, size) 112 | mstore(0x40, add(returnDataPayloadStart, size)) 113 | switch result case 0 {revert(returnDataPayloadStart, size)} 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/FixedInflationFactory.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | import "./util/DFOHub.sol"; 5 | import "./IFixedInflationFactory.sol"; 6 | 7 | contract FixedInflationFactory is IFixedInflationFactory { 8 | 9 | // fixed inflation contract implementation address 10 | address public fixedInflationImplementationAddress; 11 | 12 | // fixed inflation default extension 13 | address public override fixedInflationDefaultExtension; 14 | 15 | // double proxy address of the linked DFO 16 | address public _doubleProxy; 17 | 18 | // linked DFO exit fee 19 | uint256 private _feePercentage; 20 | 21 | // event that tracks fixed inflation contracts deployed 22 | event FixedInflationDeployed(address indexed fixedInflationAddress, address indexed sender, bytes fixedInflationInitResultData); 23 | 24 | // event that tracks logic contract address change 25 | event FixedInflationLogicSet(address indexed newAddress); 26 | 27 | // event that tracks default extension contract address change 28 | event FixedInflationDefaultExtensionSet(address indexed newAddress); 29 | 30 | // event that tracks wallet changes 31 | event FeePercentageSet(uint256 newFeePercentage); 32 | 33 | constructor(address doubleProxy, address _fixedInflationImplementationAddress, address _fixedInflationDefaultExtension, uint256 feePercentage) { 34 | _doubleProxy = doubleProxy; 35 | emit FixedInflationLogicSet(fixedInflationImplementationAddress = _fixedInflationImplementationAddress); 36 | emit FixedInflationDefaultExtensionSet(fixedInflationDefaultExtension = _fixedInflationDefaultExtension); 37 | emit FeePercentageSet(_feePercentage = feePercentage); 38 | } 39 | 40 | /** PUBLIC METHODS */ 41 | 42 | function feePercentageInfo() public override view returns (uint256, address) { 43 | return (_feePercentage, IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDWalletAddress()); 44 | } 45 | 46 | /** @dev allows the DFO to update the double proxy address. 47 | * @param newDoubleProxy new double proxy address. 48 | */ 49 | function setDoubleProxy(address newDoubleProxy) public onlyDFO { 50 | _doubleProxy = newDoubleProxy; 51 | } 52 | 53 | /** @dev change the fee percentage 54 | * @param feePercentage new fee percentage. 55 | */ 56 | function updateFeePercentage(uint256 feePercentage) public onlyDFO { 57 | emit FeePercentageSet(_feePercentage = feePercentage); 58 | } 59 | 60 | /** @dev allows the factory owner to update the logic contract address. 61 | * @param _fixedInflationImplementationAddress new fixed inflation implementation address. 62 | */ 63 | function updateLogicAddress(address _fixedInflationImplementationAddress) public onlyDFO { 64 | emit FixedInflationLogicSet(fixedInflationImplementationAddress = _fixedInflationImplementationAddress); 65 | } 66 | 67 | /** @dev allows the factory owner to update the extension contract address. 68 | * @param _fixedInflationDefaultExtension new fixed inflation extension address. 69 | */ 70 | function updateDefaultExtensionAddress(address _fixedInflationDefaultExtension) public onlyDFO { 71 | emit FixedInflationDefaultExtensionSet(fixedInflationDefaultExtension = _fixedInflationDefaultExtension); 72 | } 73 | 74 | function cloneFixedInflationDefaultExtension() public override returns(address clonedExtension) { 75 | emit ExtensionCloned(clonedExtension = _clone(fixedInflationDefaultExtension)); 76 | } 77 | 78 | /** @dev this function deploys a new FixedInflation contract and calls the encoded function passed as data. 79 | * @param data encoded initialize function for the fixed inflation contract (check FixedInflation contract code). 80 | * @return contractAddress new fixed inflation contract address. 81 | * @return initResultData new fixed inflation contract call result. 82 | */ 83 | function deploy(bytes memory data) public returns (address contractAddress, bytes memory initResultData) { 84 | initResultData = _call(contractAddress = _clone(fixedInflationImplementationAddress), data); 85 | emit FixedInflationDeployed(contractAddress, msg.sender, initResultData); 86 | } 87 | 88 | /** PRIVATE METHODS */ 89 | 90 | /** @dev clones the input contract address and returns the copied contract address. 91 | * @param original address of the original contract. 92 | * @return copy copied contract address. 93 | */ 94 | function _clone(address original) private returns (address copy) { 95 | assembly { 96 | mstore( 97 | 0, 98 | or( 99 | 0x5880730000000000000000000000000000000000000000803b80938091923cF3, 100 | mul(original, 0x1000000000000000000) 101 | ) 102 | ) 103 | copy := create(0, 0, 32) 104 | switch extcodesize(copy) 105 | case 0 { 106 | invalid() 107 | } 108 | } 109 | } 110 | 111 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 112 | assembly { 113 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 114 | let size := returndatasize() 115 | returnData := mload(0x40) 116 | mstore(returnData, size) 117 | let returnDataPayloadStart := add(returnData, 0x20) 118 | returndatacopy(returnDataPayloadStart, 0, size) 119 | mstore(0x40, add(returnDataPayloadStart, size)) 120 | switch result case 0 {revert(returnDataPayloadStart, size)} 121 | } 122 | } 123 | 124 | /** @dev onlyDFO modifier used to check for unauthorized accesses. */ 125 | modifier onlyDFO() { 126 | require(IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(msg.sender), "Unauthorized."); 127 | _; 128 | } 129 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/IFixedInflation.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FixedInflationData.sol"; 6 | 7 | interface IFixedInflation { 8 | 9 | function setEntry(FixedInflationEntry memory entryData, FixedInflationOperation[] memory operations) external; 10 | 11 | function flushBack(address[] memory tokenAddresses) external; 12 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/IFixedInflationExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./FixedInflationData.sol"; 6 | 7 | interface IFixedInflationExtension { 8 | 9 | function init(address host) external; 10 | 11 | function setHost(address host) external; 12 | 13 | function data() external view returns(address fixedInflationContract, address host); 14 | 15 | function receiveTokens(address[] memory tokenAddresses, uint256[] memory transferAmounts, uint256[] memory amountsToMint) external; 16 | 17 | function flushBack(address[] memory tokenAddresses) external; 18 | 19 | function deactivationByFailure() external; 20 | 21 | function setEntry(FixedInflationEntry memory entryData, FixedInflationOperation[] memory operations) external; 22 | 23 | function active() external view returns(bool); 24 | 25 | function setActive(bool _active) external; 26 | 27 | function burnToken(address erc20TokenAddress, uint256 value) external; 28 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/IFixedInflationFactory.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | interface IFixedInflationFactory { 5 | 6 | event ExtensionCloned(address indexed); 7 | 8 | function fixedInflationDefaultExtension() external view returns (address); 9 | 10 | function feePercentageInfo() external view returns (uint256, address); 11 | 12 | function cloneFixedInflationDefaultExtension() external returns(address clonedExtension); 13 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/dfo/DFOBasedFixedInflationExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../FixedInflationData.sol"; 6 | import "../IFixedInflationExtension.sol"; 7 | import "../util/DFOHub.sol"; 8 | import "../IFixedInflation.sol"; 9 | import "../util/IERC20.sol"; 10 | import "../util/IERC20Burnable.sol"; 11 | 12 | contract DFOBasedFixedInflationExtension is IFixedInflationExtension { 13 | 14 | string private constant FUNCTIONALITY_NAME = "manageFixedInflation"; 15 | 16 | address private _host; 17 | 18 | address private _fixedInflationContract; 19 | 20 | bool public override active; 21 | 22 | modifier fixedInflationOnly() { 23 | require(_fixedInflationContract == msg.sender, "Unauthorized"); 24 | _; 25 | } 26 | 27 | receive() external payable { 28 | } 29 | 30 | modifier hostOnly() { 31 | require(_isFromDFO(msg.sender), "Unauthorized"); 32 | _; 33 | } 34 | 35 | function init(address doubleProxyAddress) override public { 36 | require(_host == address(0), "Already init"); 37 | require((_host = doubleProxyAddress) != address(0), "blank host"); 38 | _fixedInflationContract = msg.sender; 39 | } 40 | 41 | function data() view public override returns(address fixedInflationContract, address host) { 42 | return(_fixedInflationContract, _host); 43 | } 44 | 45 | function setHost(address host) public virtual override hostOnly { 46 | _host = host; 47 | } 48 | 49 | function setActive(bool _active) public override virtual hostOnly { 50 | active = _active; 51 | } 52 | 53 | function receiveTokens(address[] memory tokenAddresses, uint256[] memory transferAmounts, uint256[] memory amountsToMint) public override fixedInflationOnly { 54 | IMVDProxy(IDoubleProxy(_host).proxy()).submit(FUNCTIONALITY_NAME, abi.encode(address(0), 0, tokenAddresses, transferAmounts, amountsToMint, _fixedInflationContract)); 55 | } 56 | 57 | function setEntry(FixedInflationEntry memory newEntry, FixedInflationOperation[] memory newOperations) public override hostOnly { 58 | IFixedInflation(_fixedInflationContract).setEntry(newEntry, newOperations); 59 | } 60 | 61 | function flushBack(address[] memory tokenAddresses) public override hostOnly { 62 | IFixedInflation(_fixedInflationContract).flushBack(tokenAddresses); 63 | address walletAddress = _getDFOWallet(); 64 | for(uint256 i = 0; i < tokenAddresses.length; i++) { 65 | _transferTo(tokenAddresses[i], walletAddress, _balanceOf(tokenAddresses[i])); 66 | } 67 | } 68 | 69 | function deactivationByFailure() public override fixedInflationOnly { 70 | active = false; 71 | } 72 | 73 | function burnToken(address erc20TokenAddress, uint256 value) external override fixedInflationOnly { 74 | _safeTransferFrom(erc20TokenAddress, _fixedInflationContract, address(this), value); 75 | _burn(erc20TokenAddress, value); 76 | } 77 | 78 | function _burn(address erc20TokenAddress, uint256 value) internal virtual { 79 | IERC20Burnable(erc20TokenAddress).burn(value); 80 | } 81 | 82 | function _getFunctionalityAddress() private view returns(address functionalityAddress) { 83 | (functionalityAddress,,,,) = IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_host).proxy()).getMVDFunctionalitiesManagerAddress()).getFunctionalityData(FUNCTIONALITY_NAME); 84 | } 85 | 86 | function _getDFOWallet() private view returns(address) { 87 | return IMVDProxy(IDoubleProxy(_host).proxy()).getMVDWalletAddress(); 88 | } 89 | 90 | function _isFromDFO(address sender) private view returns(bool) { 91 | return IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(_host).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(sender); 92 | } 93 | 94 | function _balanceOf(address tokenAddress) private view returns (uint256) { 95 | if(tokenAddress == address(0)) { 96 | return address(this).balance; 97 | } 98 | return IERC20(tokenAddress).balanceOf(address(this)); 99 | } 100 | 101 | function _transferTo(address erc20TokenAddress, address to, uint256 value) private { 102 | if(value == 0) { 103 | return; 104 | } 105 | if(erc20TokenAddress == address(0)) { 106 | (bool result,) = to.call{value:value}(""); 107 | require(result, "ETH transfer failed"); 108 | return; 109 | } 110 | _safeTransfer(erc20TokenAddress, to, value); 111 | } 112 | 113 | function _safeTransfer(address erc20TokenAddress, address to, uint256 value) private { 114 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); 115 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); 116 | } 117 | 118 | function _safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal { 119 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); 120 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); 121 | } 122 | 123 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 124 | assembly { 125 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 126 | let size := returndatasize() 127 | returnData := mload(0x40) 128 | mstore(returnData, size) 129 | let returnDataPayloadStart := add(returnData, 0x20) 130 | returndatacopy(returnDataPayloadStart, 0, size) 131 | mstore(0x40, add(returnDataPayloadStart, size)) 132 | switch result case 0 {revert(returnDataPayloadStart, size)} 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/dfo/DFOBasedFixedInflationExtensionFactory.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | import "../util/DFOHub.sol"; 5 | 6 | contract DFOBasedFixedInflationExtensionFactory { 7 | 8 | address public doubleProxy; 9 | 10 | address public model; 11 | 12 | event ExtensionCloned(address indexed extensionAddress, address indexed sender); 13 | 14 | constructor(address doubleProxyAddress, address modelAddress) { 15 | doubleProxy = doubleProxyAddress; 16 | model = modelAddress; 17 | } 18 | 19 | function setDoubleProxy(address doubleProxyAddress) public onlyDFO { 20 | doubleProxy = doubleProxyAddress; 21 | } 22 | 23 | function setModel(address modelAddress) public onlyDFO { 24 | model = modelAddress; 25 | } 26 | 27 | function cloneModel() public returns(address clonedExtension) { 28 | emit ExtensionCloned(clonedExtension = _clone(model), msg.sender); 29 | } 30 | 31 | function _clone(address original) private returns (address copy) { 32 | assembly { 33 | mstore( 34 | 0, 35 | or( 36 | 0x5880730000000000000000000000000000000000000000803b80938091923cF3, 37 | mul(original, 0x1000000000000000000) 38 | ) 39 | ) 40 | copy := create(0, 0, 32) 41 | switch extcodesize(copy) 42 | case 0 { 43 | invalid() 44 | } 45 | } 46 | } 47 | 48 | modifier onlyDFO() { 49 | require(IMVDFunctionalitiesManager(IMVDProxy(IDoubleProxy(doubleProxy).proxy()).getMVDFunctionalitiesManagerAddress()).isAuthorizedFunctionality(msg.sender), "Unauthorized."); 50 | _; 51 | } 52 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/dfo/ManageFixedInflationFunctionality.sol: -------------------------------------------------------------------------------- 1 | /* Discussion: 2 | * //discord.gg/34we8bh 3 | */ 4 | /* Description: 5 | * Fixed Inflation Management Functionality 6 | */ 7 | // SPDX-License-Identifier: MIT 8 | pragma solidity >=0.7.0; 9 | pragma abicoder v2; 10 | 11 | contract ProposalCode { 12 | 13 | string private _metadataLink; 14 | 15 | constructor(string memory metadataLink) { 16 | _metadataLink = metadataLink; 17 | } 18 | 19 | function getMetadataLink() public view returns(string memory) { 20 | return _metadataLink; 21 | } 22 | 23 | function onStart(address, address) public { 24 | IMVDProxy proxy = IMVDProxy(msg.sender); 25 | IStateHolder stateHolder = IStateHolder(proxy.getStateHolderAddress()); 26 | stateHolder.setBool(_toStateHolderKey("fixedinflation.authorized", _toString({0})), true); 27 | IFixedInflationExtension({0}).setActive(true); 28 | } 29 | 30 | function onStop(address) public { 31 | } 32 | 33 | function manageFixedInflation(address sender, uint256, address[] memory tokenAddresses, uint256[] memory transferAmounts, uint256[] memory amountsToMint, address to) public { 34 | IMVDProxy proxy = IMVDProxy(msg.sender); 35 | IStateHolder stateHolder = IStateHolder(proxy.getStateHolderAddress()); 36 | require(stateHolder.getBool(_toStateHolderKey("fixedinflation.authorized", _toString(sender))), "Unauthorized action"); 37 | for(uint256 i = 0; i < tokenAddresses.length; i++) { 38 | IERC20 token = IERC20(tokenAddresses[i]); 39 | if(amountsToMint[i] > 0) { 40 | uint256 lastAmount = token.balanceOf(msg.sender); 41 | token.mint(amountsToMint[i]); 42 | proxy.flushToWallet(address(token), false, 0); 43 | if(lastAmount > 0) { 44 | proxy.transfer(msg.sender, lastAmount, address(token)); 45 | } 46 | } 47 | proxy.transfer(to, transferAmounts[i] + amountsToMint[i], address(token)); 48 | } 49 | } 50 | 51 | function _toStateHolderKey(string memory a, string memory b) private pure returns(string memory) { 52 | return _toLowerCase(string(abi.encodePacked(a, ".", b))); 53 | } 54 | 55 | function _toString(address _addr) private pure returns(string memory) { 56 | bytes32 value = bytes32(uint256(_addr)); 57 | bytes memory alphabet = "0123456789abcdef"; 58 | 59 | bytes memory str = new bytes(42); 60 | str[0] = '0'; 61 | str[1] = 'x'; 62 | for (uint i = 0; i < 20; i++) { 63 | str[2+i*2] = alphabet[uint(uint8(value[i + 12] >> 4))]; 64 | str[3+i*2] = alphabet[uint(uint8(value[i + 12] & 0x0f))]; 65 | } 66 | return string(str); 67 | } 68 | 69 | function _toLowerCase(string memory str) private pure returns(string memory) { 70 | bytes memory bStr = bytes(str); 71 | for (uint i = 0; i < bStr.length; i++) { 72 | bStr[i] = bStr[i] >= 0x41 && bStr[i] <= 0x5A ? bytes1(uint8(bStr[i]) + 0x20) : bStr[i]; 73 | } 74 | return string(bStr); 75 | } 76 | } 77 | 78 | interface IMVDProxy { 79 | function getStateHolderAddress() external view returns(address); 80 | function getMVDWalletAddress() external view returns(address); 81 | function transfer(address receiver, uint256 value, address token) external; 82 | function flushToWallet(address tokenAddress, bool is721, uint256 tokenId) external; 83 | } 84 | 85 | interface IStateHolder { 86 | function setUint256(string calldata name, uint256 value) external returns(uint256); 87 | function getUint256(string calldata name) external view returns(uint256); 88 | function getAddress(string calldata name) external view returns(address); 89 | function setAddress(string calldata varName, address val) external returns (address); 90 | function getBool(string calldata varName) external view returns (bool); 91 | function setBool(string calldata varName, bool val) external returns(bool); 92 | function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal); 93 | } 94 | 95 | interface IERC20 { 96 | function totalSupply() external view returns (uint256); 97 | function balanceOf(address account) external view returns (uint256); 98 | function transfer(address recipient, uint256 amount) external returns (bool); 99 | function allowance(address owner, address spender) external view returns (uint256); 100 | function approve(address spender, uint256 amount) external returns (bool); 101 | function safeApprove(address spender, uint256 amount) external; 102 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 103 | function decimals() external view returns (uint8); 104 | function mint(uint256 amount) external; 105 | function burn(uint256 amount) external; 106 | } 107 | 108 | interface IFixedInflationExtension { 109 | function setActive(bool _active) external; 110 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/util/DFOHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IDoubleProxy { 6 | function proxy() external view returns (address); 7 | } 8 | 9 | interface IMVDProxy { 10 | function getMVDFunctionalitiesManagerAddress() external view returns(address); 11 | function getMVDWalletAddress() external view returns (address); 12 | function getStateHolderAddress() external view returns(address); 13 | function submit(string calldata codeName, bytes calldata data) external payable returns(bytes memory returnData); 14 | } 15 | 16 | interface IMVDFunctionalitiesManager { 17 | function getFunctionalityData(string calldata codeName) external view returns(address, uint256, string memory, address, uint256); 18 | function isAuthorizedFunctionality(address functionality) external view returns(bool); 19 | } 20 | 21 | interface IStateHolder { 22 | function getUint256(string calldata name) external view returns(uint256); 23 | function getAddress(string calldata name) external view returns(address); 24 | function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal); 25 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/util/IERC20.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | interface IERC20 { 5 | function totalSupply() external view returns(uint256); 6 | function balanceOf(address account) external view returns (uint256); 7 | function allowance(address owner, address spender) external view returns (uint256); 8 | function approve(address spender, uint256 amount) external returns (bool); 9 | function transfer(address recipient, uint256 amount) external returns (bool); 10 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 11 | 12 | function decimals() external view returns (uint8); 13 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/util/IERC20Burnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC20Burnable { 6 | function burn(uint256 amount) external; 7 | } -------------------------------------------------------------------------------- /contracts/fixed-inflation/util/IERC20Mintable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC20Mintable { 6 | function mint(address wallet, uint256 amount) external returns (bool); 7 | function burn(address wallet, uint256 amount) external returns (bool); 8 | } 9 | -------------------------------------------------------------------------------- /contracts/index/IIndex.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IIndex { 6 | 7 | function _doubleProxy() external view returns(address); 8 | 9 | function collection() external view returns(address); 10 | 11 | function setDoubleProxy(address newDoubleProxy) external; 12 | 13 | function setCollectionUri(string calldata uri) external; 14 | 15 | function info(uint256 objectId, uint256 value) external view returns(address[] memory _tokens, uint256[] memory _amounts); 16 | 17 | function mint(string calldata name, string calldata symbol, string calldata uri, address[] calldata _tokens, uint256[] calldata _amounts, uint256 value, address receiver) external payable returns(uint256 objectId, address interoperableInterfaceAddress); 18 | 19 | function mint(uint256 objectId, uint256 value, address receiver) external payable; 20 | } -------------------------------------------------------------------------------- /contracts/index/util/DFOHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IDoubleProxy { 6 | function proxy() external view returns (address); 7 | } 8 | 9 | interface IMVDProxy { 10 | function getMVDFunctionalitiesManagerAddress() external view returns(address); 11 | function getMVDWalletAddress() external view returns (address); 12 | function getStateHolderAddress() external view returns(address); 13 | function submit(string calldata codeName, bytes calldata data) external payable returns(bytes memory returnData); 14 | } 15 | 16 | interface IMVDFunctionalitiesManager { 17 | function getFunctionalityData(string calldata codeName) external view returns(address, uint256, string memory, address, uint256); 18 | function isAuthorizedFunctionality(address functionality) external view returns(bool); 19 | } 20 | 21 | interface IStateHolder { 22 | function getUint256(string calldata name) external view returns(uint256); 23 | function getAddress(string calldata name) external view returns(address); 24 | function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal); 25 | } -------------------------------------------------------------------------------- /contracts/index/util/ERC1155Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | abstract contract ERC1155Receiver { 6 | bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; 7 | 8 | mapping(bytes4 => bool) private _supportedInterfaces; 9 | 10 | constructor() { 11 | _registerInterface(_INTERFACE_ID_ERC165); 12 | _registerInterface( 13 | ERC1155Receiver(0).onERC1155Received.selector ^ 14 | ERC1155Receiver(0).onERC1155BatchReceived.selector 15 | ); 16 | } 17 | 18 | function supportsInterface(bytes4 interfaceId) public view returns (bool) { 19 | return _supportedInterfaces[interfaceId]; 20 | } 21 | 22 | function _registerInterface(bytes4 interfaceId) internal virtual { 23 | require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); 24 | _supportedInterfaces[interfaceId] = true; 25 | } 26 | 27 | function onERC1155Received( 28 | address operator, 29 | address from, 30 | uint256 id, 31 | uint256 value, 32 | bytes calldata data 33 | ) 34 | external 35 | virtual 36 | returns(bytes4); 37 | 38 | function onERC1155BatchReceived( 39 | address operator, 40 | address from, 41 | uint256[] calldata ids, 42 | uint256[] calldata values, 43 | bytes calldata data 44 | ) 45 | external 46 | virtual 47 | returns(bytes4); 48 | } 49 | -------------------------------------------------------------------------------- /contracts/index/util/IERC1155.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC1155 { 6 | 7 | event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); 8 | 9 | event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); 10 | 11 | event ApprovalForAll(address indexed account, address indexed operator, bool approved); 12 | 13 | event URI(string value, uint256 indexed id); 14 | 15 | function balanceOf(address account, uint256 id) external view returns (uint256); 16 | 17 | function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); 18 | 19 | function setApprovalForAll(address operator, bool approved) external; 20 | 21 | function isApprovedForAll(address account, address operator) external view returns (bool); 22 | 23 | function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; 24 | 25 | function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/index/util/IERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC20 { 6 | 7 | function totalSupply() external view returns (uint256); 8 | 9 | function balanceOf(address account) external view returns (uint256); 10 | 11 | function transfer(address recipient, uint256 amount) external returns (bool); 12 | 13 | function allowance(address owner, address spender) external view returns (uint256); 14 | 15 | function approve(address spender, uint256 amount) external returns (bool); 16 | 17 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 18 | 19 | function decimals() external view returns (uint8); 20 | } 21 | -------------------------------------------------------------------------------- /contracts/index/util/IERC20WrapperV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IEthItem.sol"; 6 | 7 | interface IERC20WrapperV1 is IEthItem { 8 | 9 | function source(uint256 objectId) external view returns (address erc20TokenAddress); 10 | 11 | function object(address erc20TokenAddress) external view returns (uint256 objectId); 12 | 13 | function mint(address erc20TokenAddress, uint256 amount) external returns (uint256 objectId, address wrapperAddress); 14 | 15 | function mintETH() external payable returns (uint256 objectId, address wrapperAddress); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/index/util/IEthItem.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IERC1155.sol"; 6 | import "./IEthItemInteroperableInterface.sol"; 7 | 8 | interface IEthItem is IERC1155 { 9 | 10 | function name() external view returns (string memory); 11 | 12 | function symbol() external view returns (string memory); 13 | 14 | function totalSupply(uint256 objectId) external view returns (uint256); 15 | 16 | function name(uint256 objectId) external view returns (string memory); 17 | 18 | function symbol(uint256 objectId) external view returns (string memory); 19 | 20 | function decimals(uint256 objectId) external view returns (uint256); 21 | 22 | function uri(uint256 objectId) external view returns (string memory); 23 | 24 | function mainInterfaceVersion() external pure returns(uint256 ethItemInteroperableVersion); 25 | 26 | function toInteroperableInterfaceAmount(uint256 objectId, uint256 ethItemAmount) external view returns (uint256 interoperableInterfaceAmount); 27 | 28 | function toMainInterfaceAmount(uint256 objectId, uint256 erc20WrapperAmount) external view returns (uint256 mainInterfaceAmount); 29 | 30 | function interoperableInterfaceModel() external view returns (address, uint256); 31 | 32 | function asInteroperable(uint256 objectId) external view returns (IEthItemInteroperableInterface); 33 | 34 | function emitTransferSingleEvent(address sender, address from, address to, uint256 objectId, uint256 amount) external; 35 | 36 | function mint(uint256 amount, string calldata partialUri) 37 | external 38 | returns (uint256, address); 39 | 40 | function burn( 41 | uint256 objectId, 42 | uint256 amount 43 | ) external; 44 | 45 | function burnBatch( 46 | uint256[] calldata objectIds, 47 | uint256[] calldata amounts 48 | ) external; 49 | } -------------------------------------------------------------------------------- /contracts/index/util/IEthItemInteroperableInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IERC20.sol"; 6 | 7 | interface IEthItemInteroperableInterface is IERC20 { 8 | 9 | function mainInterface() external view returns (address); 10 | 11 | function objectId() external view returns (uint256); 12 | 13 | function mint(address owner, uint256 amount) external; 14 | 15 | function burn(address owner, uint256 amount) external; 16 | 17 | function permitNonce(address sender) external view returns(uint256); 18 | 19 | function permit(address owner, address spender, uint value, uint8 v, bytes32 r, bytes32 s) external; 20 | 21 | function interoperableInterfaceVersion() external pure returns(uint256 ethItemInteroperableInterfaceVersion); 22 | } -------------------------------------------------------------------------------- /contracts/index/util/IEthItemOrchestrator.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IEthItemOrchestrator { 6 | function createNative(bytes calldata modelInitPayload, string calldata ens) 7 | external 8 | returns (address newNativeAddress, bytes memory modelInitCallResponse); 9 | } -------------------------------------------------------------------------------- /contracts/index/util/INativeV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IEthItem.sol"; 6 | 7 | interface INativeV1 is IEthItem { 8 | 9 | function init(string calldata name, string calldata symbol, bool hasDecimals, string calldata collectionUri, address extensionAddress, bytes calldata extensionInitPayload) external returns(bytes memory extensionInitCallResponse); 10 | 11 | function extension() external view returns (address extensionAddress); 12 | 13 | function canMint(address operator) external view returns (bool result); 14 | 15 | function isEditable(uint256 objectId) external view returns (bool result); 16 | 17 | function releaseExtension() external; 18 | 19 | function uri() external view returns (string memory); 20 | 21 | function decimals() external view returns (uint256); 22 | 23 | function mint(uint256 amount, string calldata tokenName, string calldata tokenSymbol, string calldata objectUri, bool editable) external returns (uint256 objectId, address tokenAddress); 24 | 25 | function mint(uint256 amount, string calldata tokenName, string calldata tokenSymbol, string calldata objectUri) external returns (uint256 objectId, address tokenAddress); 26 | 27 | function mint(uint256 objectId, uint256 amount) external; 28 | 29 | function makeReadOnly(uint256 objectId) external; 30 | 31 | function setUri(string calldata newUri) external; 32 | 33 | function setUri(uint256 objectId, string calldata newUri) external; 34 | } -------------------------------------------------------------------------------- /contracts/presto/IPresto.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./PrestoData.sol"; 6 | 7 | interface IPresto { 8 | 9 | function ONE_HUNDRED() external view returns (uint256); 10 | function doubleProxy() external view returns (address); 11 | function feePercentage() external view returns (uint256); 12 | 13 | function feePercentageInfo() external view returns (uint256, address); 14 | 15 | function setDoubleProxy(address _doubleProxy) external; 16 | 17 | function setFeePercentage(uint256 _feePercentage) external; 18 | 19 | function execute(PrestoOperation[] memory operations) external payable; 20 | } -------------------------------------------------------------------------------- /contracts/presto/IPrestoUniV3.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./PrestoDataUniV3.sol"; 6 | 7 | interface IPrestoUniV3 { 8 | 9 | function ONE_HUNDRED() external view returns (uint256); 10 | function doubleProxy() external view returns (address); 11 | function feePercentage() external view returns (uint256); 12 | 13 | function feePercentageInfo() external view returns (uint256, address); 14 | 15 | function setDoubleProxy(address _doubleProxy) external; 16 | 17 | function setFeePercentage(uint256 _feePercentage) external; 18 | 19 | function execute(PrestoOperation[] memory operations) external payable returns(uint256[] memory outputAmounts); 20 | } -------------------------------------------------------------------------------- /contracts/presto/PrestoData.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | struct PrestoOperation { 5 | 6 | address inputTokenAddress; 7 | uint256 inputTokenAmount; 8 | 9 | address ammPlugin; 10 | address[] liquidityPoolAddresses; 11 | address[] swapPath; 12 | bool enterInETH; 13 | bool exitInETH; 14 | 15 | address[] receivers; 16 | uint256[] receiversPercentages; 17 | } -------------------------------------------------------------------------------- /contracts/presto/PrestoDataUniV3.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | struct PrestoOperation { 5 | 6 | address inputTokenAddress; 7 | uint256 inputTokenAmount; 8 | 9 | address ammPlugin; 10 | address[] liquidityPoolAddresses; 11 | address[] swapPath; 12 | bool enterInETH; 13 | bool exitInETH; 14 | 15 | uint256[] tokenMins; 16 | 17 | address[] receivers; 18 | uint256[] receiversPercentages; 19 | } -------------------------------------------------------------------------------- /contracts/presto/util/DFOHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IDoubleProxy { 6 | function proxy() external view returns (address); 7 | } 8 | 9 | interface IMVDProxy { 10 | function getMVDFunctionalitiesManagerAddress() external view returns(address); 11 | function getMVDWalletAddress() external view returns (address); 12 | function getStateHolderAddress() external view returns(address); 13 | function submit(string calldata codeName, bytes calldata data) external payable returns(bytes memory returnData); 14 | } 15 | 16 | interface IMVDFunctionalitiesManager { 17 | function isAuthorizedFunctionality(address functionality) external view returns(bool); 18 | } 19 | 20 | interface IStateHolder { 21 | function getUint256(string calldata name) external view returns(uint256); 22 | function getAddress(string calldata name) external view returns(address); 23 | function clear(string calldata varName) external returns(string memory oldDataType, bytes memory oldVal); 24 | } -------------------------------------------------------------------------------- /contracts/presto/util/ERC1155Receiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | abstract contract ERC1155Receiver { 6 | bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; 7 | 8 | mapping(bytes4 => bool) private _supportedInterfaces; 9 | 10 | constructor() { 11 | _registerInterface(_INTERFACE_ID_ERC165); 12 | _registerInterface( 13 | ERC1155Receiver(0).onERC1155Received.selector ^ 14 | ERC1155Receiver(0).onERC1155BatchReceived.selector 15 | ); 16 | } 17 | 18 | function supportsInterface(bytes4 interfaceId) public view returns (bool) { 19 | return _supportedInterfaces[interfaceId]; 20 | } 21 | 22 | function _registerInterface(bytes4 interfaceId) internal virtual { 23 | require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); 24 | _supportedInterfaces[interfaceId] = true; 25 | } 26 | 27 | function onERC1155Received( 28 | address operator, 29 | address from, 30 | uint256 id, 31 | uint256 value, 32 | bytes calldata data 33 | ) 34 | external 35 | virtual 36 | returns(bytes4); 37 | 38 | function onERC1155BatchReceived( 39 | address operator, 40 | address from, 41 | uint256[] calldata ids, 42 | uint256[] calldata values, 43 | bytes calldata data 44 | ) 45 | external 46 | virtual 47 | returns(bytes4); 48 | } 49 | -------------------------------------------------------------------------------- /contracts/presto/util/IERC1155.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC1155 { 6 | 7 | event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); 8 | 9 | event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); 10 | 11 | event ApprovalForAll(address indexed account, address indexed operator, bool approved); 12 | 13 | event URI(string value, uint256 indexed id); 14 | 15 | function balanceOf(address account, uint256 id) external view returns (uint256); 16 | 17 | function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); 18 | 19 | function setApprovalForAll(address operator, bool approved) external; 20 | 21 | function isApprovedForAll(address account, address operator) external view returns (bool); 22 | 23 | function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; 24 | 25 | function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external; 26 | } 27 | -------------------------------------------------------------------------------- /contracts/presto/util/IERC20.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | 4 | interface IERC20 { 5 | function totalSupply() external view returns(uint256); 6 | function balanceOf(address account) external view returns (uint256); 7 | function allowance(address owner, address spender) external view returns (uint256); 8 | function approve(address spender, uint256 amount) external returns (bool); 9 | function transfer(address recipient, uint256 amount) external returns (bool); 10 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 11 | 12 | function decimals() external view returns (uint8); 13 | } -------------------------------------------------------------------------------- /contracts/presto/util/IERC20Burnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | interface IERC20Burnable { 6 | function burn(uint256 amount) external; 7 | } -------------------------------------------------------------------------------- /contracts/presto/util/IEthItem.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IERC1155.sol"; 6 | import "./IEthItemInteroperableInterface.sol"; 7 | 8 | interface IEthItem is IERC1155 { 9 | 10 | function name() external view returns (string memory); 11 | 12 | function symbol() external view returns (string memory); 13 | 14 | function totalSupply(uint256 objectId) external view returns (uint256); 15 | 16 | function name(uint256 objectId) external view returns (string memory); 17 | 18 | function symbol(uint256 objectId) external view returns (string memory); 19 | 20 | function decimals(uint256 objectId) external view returns (uint256); 21 | 22 | function uri(uint256 objectId) external view returns (string memory); 23 | 24 | function mainInterfaceVersion() external pure returns(uint256 ethItemInteroperableVersion); 25 | 26 | function toInteroperableInterfaceAmount(uint256 objectId, uint256 ethItemAmount) external view returns (uint256 interoperableInterfaceAmount); 27 | 28 | function toMainInterfaceAmount(uint256 objectId, uint256 erc20WrapperAmount) external view returns (uint256 mainInterfaceAmount); 29 | 30 | function interoperableInterfaceModel() external view returns (address, uint256); 31 | 32 | function asInteroperable(uint256 objectId) external view returns (IEthItemInteroperableInterface); 33 | 34 | function emitTransferSingleEvent(address sender, address from, address to, uint256 objectId, uint256 amount) external; 35 | 36 | function mint(uint256 amount, string calldata partialUri) 37 | external 38 | returns (uint256, address); 39 | 40 | function burn( 41 | uint256 objectId, 42 | uint256 amount 43 | ) external; 44 | 45 | function burnBatch( 46 | uint256[] calldata objectIds, 47 | uint256[] calldata amounts 48 | ) external; 49 | } -------------------------------------------------------------------------------- /contracts/presto/util/IEthItemInteroperableInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IERC20.sol"; 6 | 7 | interface IEthItemInteroperableInterface is IERC20 { 8 | 9 | function mainInterface() external view returns (address); 10 | 11 | function objectId() external view returns (uint256); 12 | 13 | function mint(address owner, uint256 amount) external; 14 | 15 | function burn(address owner, uint256 amount) external; 16 | 17 | function permitNonce(address sender) external view returns(uint256); 18 | 19 | function permit(address owner, address spender, uint value, uint8 v, bytes32 r, bytes32 s) external; 20 | 21 | function interoperableInterfaceVersion() external pure returns(uint256 ethItemInteroperableInterfaceVersion); 22 | } -------------------------------------------------------------------------------- /contracts/presto/util/INativeV1.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.7.0; 4 | 5 | import "./IEthItem.sol"; 6 | 7 | interface INativeV1 is IEthItem { 8 | 9 | function init(string calldata name, string calldata symbol, bool hasDecimals, string calldata collectionUri, address extensionAddress, bytes calldata extensionInitPayload) external returns(bytes memory extensionInitCallResponse); 10 | 11 | function extension() external view returns (address extensionAddress); 12 | 13 | function canMint(address operator) external view returns (bool result); 14 | 15 | function isEditable(uint256 objectId) external view returns (bool result); 16 | 17 | function releaseExtension() external; 18 | 19 | function uri() external view returns (string memory); 20 | 21 | function decimals() external view returns (uint256); 22 | 23 | function mint(uint256 amount, string calldata tokenName, string calldata tokenSymbol, string calldata objectUri, bool editable) external returns (uint256 objectId, address tokenAddress); 24 | 25 | function mint(uint256 amount, string calldata tokenName, string calldata tokenSymbol, string calldata objectUri) external returns (uint256 objectId, address tokenAddress); 26 | 27 | function mint(uint256 objectId, uint256 amount) external; 28 | 29 | function makeReadOnly(uint256 objectId) external; 30 | 31 | function setUri(string calldata newUri) external; 32 | 33 | function setUri(uint256 objectId, string calldata newUri) external; 34 | } -------------------------------------------------------------------------------- /contracts/presto/verticalizations/FarmingPresto.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../IPresto.sol"; 6 | import "../util/IERC20.sol"; 7 | import "../../amm-aggregator/common/IAMM.sol"; 8 | import "../../farming/IFarmMain.sol"; 9 | import "../util/INativeV1.sol"; 10 | 11 | contract FarmingPresto { 12 | 13 | mapping(address => uint256) private _tokenIndex; 14 | address[] private _tokensToTransfer; 15 | uint256[] private _tokenAmounts; 16 | PrestoOperation[] private _operations; 17 | 18 | receive() external payable { 19 | } 20 | 21 | function openPosition( 22 | address prestoAddress, 23 | PrestoOperation[] memory operations, 24 | address farmMainAddress, 25 | FarmingPositionRequest memory request 26 | ) public payable returns(uint256 positionId) { 27 | request.positionOwner = request.positionOwner != address(0) ? request.positionOwner : msg.sender; 28 | uint256 eth = _transferToMeAndCheckAllowance(operations, prestoAddress); 29 | IPresto(prestoAddress).execute{value : eth}(_operations); 30 | IFarmMain farmMain = IFarmMain(farmMainAddress); 31 | (address[] memory tokenAddresses, uint256 ethereumValue) = _calculateAmountsAndApprove(farmMain, request.setupIndex, request.amount); 32 | positionId = farmMain.openPosition{value : ethereumValue}(request); 33 | _flushAndClear(tokenAddresses, msg.sender); 34 | } 35 | 36 | function _calculateAmountsAndApprove(IFarmMain farmMain, uint256 setupIndex, uint256 requestAmount) private returns(address[] memory tokenAddresses, uint256 ethereumValue) { 37 | (, FarmingSetupInfo memory setupInfo) = farmMain.setup(setupIndex); 38 | uint256[] memory tokensAmounts; 39 | (, tokensAmounts, tokenAddresses) = IAMM(setupInfo.ammPlugin).byTokenAmount(setupInfo.liquidityPoolTokenAddress, setupInfo.mainTokenAddress, requestAmount); 40 | for(uint256 i = 0; i < tokenAddresses.length; i++) { 41 | if(setupInfo.involvingETH && tokenAddresses[i] == setupInfo.ethereumAddress) { 42 | ethereumValue = tokensAmounts[i]; 43 | } 44 | if(tokenAddresses[i] != address(0)) { 45 | _safeApprove(tokenAddresses[i], address(farmMain), tokensAmounts[i]); 46 | } 47 | } 48 | } 49 | 50 | function _flushAndClear(address[] memory tokenAddresses, address receiver) private { 51 | for(uint256 i = 0; i < tokenAddresses.length; i++) { 52 | if(_tokensToTransfer.length == 0 || _tokensToTransfer[_tokenIndex[tokenAddresses[i]]] != tokenAddresses[i]) { 53 | _safeTransfer(tokenAddresses[i], receiver, _balanceOf(tokenAddresses[i])); 54 | } 55 | } 56 | if(_tokensToTransfer.length == 0 || _tokensToTransfer[_tokenIndex[address(0)]] != address(0)) { 57 | _safeTransfer(address(0), receiver, address(this).balance); 58 | } 59 | _flushAndClear(receiver); 60 | } 61 | 62 | function _transferToMeAndCheckAllowance(PrestoOperation[] memory operations, address operator) private returns (uint256 eth) { 63 | eth = _collectTokensAndCheckAllowance(operations, operator); 64 | for(uint256 i = 0; i < _tokensToTransfer.length; i++) { 65 | if(_tokensToTransfer[i] == address(0)) { 66 | require(msg.value >= _tokenAmounts[i], "Incorrect ETH value"); 67 | } else { 68 | _safeTransferFrom(_tokensToTransfer[i], msg.sender, address(this), _tokenAmounts[i]); 69 | } 70 | } 71 | } 72 | 73 | function _collectTokensAndCheckAllowance(PrestoOperation[] memory operations, address operator) private returns (uint256 eth) { 74 | for(uint256 i = 0; i < operations.length; i++) { 75 | PrestoOperation memory operation = operations[i]; 76 | require(operation.ammPlugin == address(0) || operation.liquidityPoolAddresses.length > 0, "AddLiquidity not allowed"); 77 | _collectTokenData(operation.ammPlugin != address(0) && operation.enterInETH ? address(0) : operation.inputTokenAddress, operation.inputTokenAmount); 78 | if(operation.ammPlugin != address(0)) { 79 | _operations.push(operation); 80 | if(operation.inputTokenAddress == address(0) || operation.enterInETH) { 81 | eth += operation.inputTokenAmount; 82 | } 83 | } 84 | } 85 | for(uint256 i = 0 ; i < _tokensToTransfer.length; i++) { 86 | if(_tokensToTransfer[i] != address(0)) { 87 | _safeApprove(_tokensToTransfer[i], operator, _tokenAmounts[i]); 88 | } 89 | } 90 | } 91 | 92 | function _collectTokenData(address inputTokenAddress, uint256 inputTokenAmount) private { 93 | if(inputTokenAmount == 0) { 94 | return; 95 | } 96 | 97 | uint256 position = _tokenIndex[inputTokenAddress]; 98 | 99 | if(_tokensToTransfer.length == 0 || _tokensToTransfer[position] != inputTokenAddress) { 100 | _tokenIndex[inputTokenAddress] = (position = _tokensToTransfer.length); 101 | _tokensToTransfer.push(inputTokenAddress); 102 | _tokenAmounts.push(0); 103 | } 104 | _tokenAmounts[position] = _tokenAmounts[position] + inputTokenAmount; 105 | } 106 | 107 | function _flushAndClear(address receiver) private { 108 | for(uint256 i = 0; i < _tokensToTransfer.length; i++) { 109 | _safeTransfer(_tokensToTransfer[i], receiver, _balanceOf(_tokensToTransfer[i])); 110 | delete _tokenIndex[_tokensToTransfer[i]]; 111 | } 112 | delete _tokensToTransfer; 113 | delete _tokenAmounts; 114 | delete _operations; 115 | } 116 | 117 | function _balanceOf(address tokenAddress) private view returns(uint256) { 118 | if(tokenAddress == address(0)) { 119 | return address(this).balance; 120 | } 121 | return IERC20(tokenAddress).balanceOf(address(this)); 122 | } 123 | 124 | function _safeApprove(address erc20TokenAddress, address to, uint256 value) internal { 125 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, to, value)); 126 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); 127 | } 128 | 129 | function _safeTransfer(address erc20TokenAddress, address to, uint256 value) private { 130 | if(value == 0) { 131 | return; 132 | } 133 | if(erc20TokenAddress == address(0)) { 134 | (bool result,) = to.call{value:value}(""); 135 | require(result, "ETH transfer failed"); 136 | return; 137 | } 138 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); 139 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); 140 | } 141 | 142 | function _safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal { 143 | bytes memory returnData = _call(erc20TokenAddress, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); 144 | require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); 145 | } 146 | 147 | function _call(address location, bytes memory payload) private returns(bytes memory returnData) { 148 | assembly { 149 | let result := call(gas(), location, 0, add(payload, 0x20), mload(payload), 0, 0) 150 | let size := returndatasize() 151 | returnData := mload(0x40) 152 | mstore(returnData, size) 153 | let returnDataPayloadStart := add(returnData, 0x20) 154 | returndatacopy(returnDataPayloadStart, 0, size) 155 | mstore(0x40, add(returnDataPayloadStart, size)) 156 | switch result case 0 {revert(returnDataPayloadStart, size)} 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IMulticall.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IMulticall { 6 | function multicall(bytes[] memory data) external payable returns (bytes[] memory results); 7 | } 8 | -------------------------------------------------------------------------------- /contracts/util/uniswapV3/INonfungiblePositionManager.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./IMulticall.sol"; 6 | import "./IPeripheryImmutableState.sol"; 7 | import "./IPeripheryPayments.sol"; 8 | 9 | interface INonfungiblePositionManager is IMulticall, IPeripheryImmutableState, IPeripheryPayments { 10 | function setApprovalForAll(address operator, bool _approved) external; 11 | function isApprovedForAll(address owner, address operator) external view returns (bool); 12 | function transferFrom(address from, address to, uint256 tokenId) external; 13 | function safeTransferFrom( 14 | address from, 15 | address to, 16 | uint256 tokenId, 17 | bytes memory data 18 | ) external; 19 | function positions(uint256 tokenId) 20 | external 21 | view 22 | returns ( 23 | uint96 nonce, 24 | address operator, 25 | address token0, 26 | address token1, 27 | uint24 fee, 28 | int24 tickLower, 29 | int24 tickUpper, 30 | uint128 liquidity, 31 | uint256 feeGrowthInside0LastX128, 32 | uint256 feeGrowthInside1LastX128, 33 | uint128 tokensOwed0, 34 | uint128 tokensOwed1 35 | ); 36 | 37 | struct MintParams { 38 | address token0; 39 | address token1; 40 | uint24 fee; 41 | int24 tickLower; 42 | int24 tickUpper; 43 | uint256 amount0Desired; 44 | uint256 amount1Desired; 45 | uint256 amount0Min; 46 | uint256 amount1Min; 47 | address recipient; 48 | uint256 deadline; 49 | } 50 | 51 | function mint(MintParams memory params) 52 | external 53 | payable 54 | returns ( 55 | uint256 tokenId, 56 | uint128 liquidity, 57 | uint256 amount0, 58 | uint256 amount1 59 | ); 60 | 61 | struct IncreaseLiquidityParams { 62 | uint256 tokenId; 63 | uint256 amount0Desired; 64 | uint256 amount1Desired; 65 | uint256 amount0Min; 66 | uint256 amount1Min; 67 | uint256 deadline; 68 | } 69 | 70 | function increaseLiquidity(IncreaseLiquidityParams memory params) 71 | external 72 | payable 73 | returns ( 74 | uint128 liquidity, 75 | uint256 amount0, 76 | uint256 amount1 77 | ); 78 | 79 | struct DecreaseLiquidityParams { 80 | uint256 tokenId; 81 | uint128 liquidity; 82 | uint256 amount0Min; 83 | uint256 amount1Min; 84 | uint256 deadline; 85 | } 86 | 87 | function decreaseLiquidity(DecreaseLiquidityParams memory params) 88 | external 89 | payable 90 | returns (uint256 amount0, uint256 amount1); 91 | 92 | struct CollectParams { 93 | uint256 tokenId; 94 | address recipient; 95 | uint128 amount0Max; 96 | uint128 amount1Max; 97 | } 98 | 99 | function collect(CollectParams memory params) external payable returns (uint256 amount0, uint256 amount1); 100 | 101 | function burn(uint256 tokenId) external payable; 102 | } -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IPeripheryImmutableState.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IPeripheryImmutableState { 6 | function factory() external view returns (address); 7 | 8 | function WETH9() external view returns (address); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IPeripheryPayments.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IPeripheryPayments { 6 | 7 | function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; 8 | 9 | function refundETH() external payable; 10 | 11 | function sweepToken( 12 | address token, 13 | uint256 amountMinimum, 14 | address recipient 15 | ) external payable; 16 | } 17 | -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IPoolInitializer.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IPoolInitializer { 6 | function createAndInitializePoolIfNecessary( 7 | address token0, 8 | address token1, 9 | uint24 fee, 10 | uint160 sqrtPriceX96 11 | ) external payable returns (address pool); 12 | } -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IQuoter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IQuoter { 6 | 7 | function quoteExactInput(bytes memory path, uint256 amountIn) external view returns (uint256 amountOut); 8 | 9 | function quoteExactInputSingle( 10 | address tokenIn, 11 | address tokenOut, 12 | uint24 fee, 13 | uint256 amountIn, 14 | uint160 sqrtPriceLimitX96 15 | ) external returns (uint256 amountOut); 16 | 17 | function quoteExactOutput(bytes memory path, uint256 amountOut) external view returns (uint256 amountIn); 18 | 19 | function quoteExactOutputSingle( 20 | address tokenIn, 21 | address tokenOut, 22 | uint24 fee, 23 | uint256 amountOut, 24 | uint160 sqrtPriceLimitX96 25 | ) external returns (uint256 amountIn); 26 | } 27 | -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IQuoterV2.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IQuoterV2 { 6 | function quoteExactInput(bytes memory path, uint256 amountIn) 7 | external 8 | returns ( 9 | uint256 amountOut, 10 | uint160[] memory sqrtPriceX96AfterList, 11 | uint32[] memory initializedTicksCrossedList, 12 | uint256 gasEstimate 13 | ); 14 | 15 | struct QuoteExactInputSingleParams { 16 | address tokenIn; 17 | address tokenOut; 18 | uint256 amountIn; 19 | uint24 fee; 20 | uint160 sqrtPriceLimitX96; 21 | } 22 | 23 | function quoteExactInputSingle(QuoteExactInputSingleParams memory params) 24 | external 25 | returns ( 26 | uint256 amountOut, 27 | uint160 sqrtPriceX96After, 28 | uint32 initializedTicksCrossed, 29 | uint256 gasEstimate 30 | ); 31 | 32 | function quoteExactOutput(bytes memory path, uint256 amountOut) 33 | external 34 | returns ( 35 | uint256 amountIn, 36 | uint160[] memory sqrtPriceX96AfterList, 37 | uint32[] memory initializedTicksCrossedList, 38 | uint256 gasEstimate 39 | ); 40 | 41 | struct QuoteExactOutputSingleParams { 42 | address tokenIn; 43 | address tokenOut; 44 | uint256 amount; 45 | uint24 fee; 46 | uint160 sqrtPriceLimitX96; 47 | } 48 | 49 | function quoteExactOutputSingle(QuoteExactOutputSingleParams memory params) 50 | external 51 | returns ( 52 | uint256 amountIn, 53 | uint160 sqrtPriceX96After, 54 | uint32 initializedTicksCrossed, 55 | uint256 gasEstimate 56 | ); 57 | } 58 | -------------------------------------------------------------------------------- /contracts/util/uniswapV3/ISwapRouter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "./IMulticall.sol"; 6 | import "./IPeripheryImmutableState.sol"; 7 | import "./IPeripheryPayments.sol"; 8 | 9 | interface ISwapRouter is IMulticall, IPeripheryImmutableState, IPeripheryPayments { 10 | struct ExactInputSingleParams { 11 | address tokenIn; 12 | address tokenOut; 13 | uint24 fee; 14 | address recipient; 15 | uint256 deadline; 16 | uint256 amountIn; 17 | uint256 amountOutMinimum; 18 | uint160 sqrtPriceLimitX96; 19 | } 20 | 21 | function exactInputSingle(ExactInputSingleParams memory params) external payable returns (uint256 amountOut); 22 | 23 | struct ExactInputParams { 24 | bytes path; 25 | address recipient; 26 | uint256 deadline; 27 | uint256 amountIn; 28 | uint256 amountOutMinimum; 29 | } 30 | 31 | function exactInput(ExactInputParams memory params) external payable returns (uint256 amountOut); 32 | 33 | struct ExactOutputSingleParams { 34 | address tokenIn; 35 | address tokenOut; 36 | uint24 fee; 37 | address recipient; 38 | uint256 deadline; 39 | uint256 amountOut; 40 | uint256 amountInMaximum; 41 | uint160 sqrtPriceLimitX96; 42 | } 43 | 44 | function exactOutputSingle(ExactOutputSingleParams memory params) external payable returns (uint256 amountIn); 45 | 46 | struct ExactOutputParams { 47 | bytes path; 48 | address recipient; 49 | uint256 deadline; 50 | uint256 amountOut; 51 | uint256 amountInMaximum; 52 | } 53 | 54 | function exactOutput(ExactOutputParams memory params) external payable returns (uint256 amountIn); 55 | } -------------------------------------------------------------------------------- /contracts/util/uniswapV3/ITickLens.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface ITickLens { 6 | struct PopulatedTick { 7 | int24 tick; 8 | int128 liquidityNet; 9 | uint128 liquidityGross; 10 | } 11 | 12 | function getPopulatedTicksInWord(address pool, int16 tickBitmapIndex) 13 | external 14 | view 15 | returns (PopulatedTick[] memory populatedTicks); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IUniswapV3Factory.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IUniswapV3Factory { 6 | event OwnerChanged(address indexed oldOwner, address indexed newOwner); 7 | 8 | event PoolCreated( 9 | address indexed token0, 10 | address indexed token1, 11 | uint24 indexed fee, 12 | int24 tickSpacing, 13 | address pool 14 | ); 15 | 16 | event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing); 17 | 18 | function owner() external view returns (address); 19 | 20 | function feeAmountTickSpacing(uint24 fee) external view returns (int24); 21 | 22 | function getPool( 23 | address tokenA, 24 | address tokenB, 25 | uint24 fee 26 | ) external view returns (address pool); 27 | 28 | function createPool( 29 | address tokenA, 30 | address tokenB, 31 | uint24 fee 32 | ) external returns (address pool); 33 | 34 | function setOwner(address _owner) external; 35 | 36 | function enableFeeAmount(uint24 fee, int24 tickSpacing) external; 37 | } -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IUniswapV3MintCallback.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IUniswapV3MintCallback { 6 | function uniswapV3MintCallback( 7 | uint256 amount0Owed, 8 | uint256 amount1Owed, 9 | bytes memory data 10 | ) external; 11 | } -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IUniswapV3Pool.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IUniswapV3Pool { 6 | function factory() external view returns (address); 7 | function token0() external view returns (address); 8 | function token1() external view returns (address); 9 | function fee() external view returns (uint24); 10 | function tickSpacing() external view returns (int24); 11 | function maxLiquidityPerTick() external view returns (uint128); 12 | function liquidity() external view returns (uint128); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/util/uniswapV3/IUniswapV3PoolActions.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | interface IUniswapV3PoolActions { 6 | 7 | function initialize(uint160 sqrtPriceX96) external; 8 | 9 | function mint( 10 | address recipient, 11 | int24 tickLower, 12 | int24 tickUpper, 13 | uint128 amount, 14 | bytes memory data 15 | ) external returns (uint256 amount0, uint256 amount1); 16 | 17 | function collect( 18 | address recipient, 19 | int24 tickLower, 20 | int24 tickUpper, 21 | uint128 amount0Requested, 22 | uint128 amount1Requested 23 | ) external returns (uint128 amount0, uint128 amount1); 24 | 25 | function burn( 26 | int24 tickLower, 27 | int24 tickUpper, 28 | uint128 amount 29 | ) external returns (uint256 amount0, uint256 amount1); 30 | 31 | function swap( 32 | address recipient, 33 | bool zeroForOne, 34 | int256 amountSpecified, 35 | uint160 sqrtPriceLimitX96, 36 | bytes memory data 37 | ) external returns (int256 amount0, int256 amount1); 38 | 39 | function flash( 40 | address recipient, 41 | uint256 amount0, 42 | uint256 amount1, 43 | bytes memory data 44 | ) external; 45 | 46 | function increaseObservationCardinalityNext(uint16 observationCardinalityNext) external; 47 | } -------------------------------------------------------------------------------- /contracts/util/uniswapV3/PoolAddress.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | library PoolAddress { 6 | bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54; 7 | 8 | struct PoolKey { 9 | address token0; 10 | address token1; 11 | uint24 fee; 12 | } 13 | 14 | function getPoolKey( 15 | address tokenA, 16 | address tokenB, 17 | uint24 fee 18 | ) internal pure returns (PoolKey memory) { 19 | if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); 20 | return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); 21 | } 22 | 23 | function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { 24 | require(key.token0 < key.token1); 25 | pool = address( 26 | uint160( 27 | uint256( 28 | keccak256( 29 | abi.encodePacked( 30 | hex'ff', 31 | factory, 32 | keccak256(abi.encode(key.token0, key.token1, key.fee)), 33 | POOL_INIT_CODE_HASH 34 | ) 35 | ) 36 | ) 37 | ) 38 | ); 39 | } 40 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ethereansos/covenants-core", 3 | "version": "1.0.0", 4 | "description": "Covenants", 5 | "scripts": { 6 | "compile": "multiverse compile", 7 | "flat": "multiverse flat", 8 | "start": "multiverse", 9 | "test": "mocha" 10 | }, 11 | "multiverse": { 12 | "knowledgeBase": "resources/knowledgeBase", 13 | "solidityVersion": "0.7.6" 14 | }, 15 | "mocha": { 16 | "timeout": false, 17 | "require": "@ethereansos/multiverse" 18 | }, 19 | "author": "", 20 | "license": "ISC", 21 | "dependencies": { 22 | "@ethereansos/multiverse": "git+https://github.com/EthereansOS/multiverse.git" 23 | } 24 | } -------------------------------------------------------------------------------- /procedures/misc.js: -------------------------------------------------------------------------------- 1 | var { 2 | VOID_ETHEREUM_ADDRESS, 3 | VOID_BYTES32, 4 | blockchainCall, 5 | compile, 6 | deployContract, 7 | abi, 8 | MAX_UINT256, 9 | web3Utils, 10 | fromDecimals, 11 | toDecimals, 12 | sendBlockchainTransaction, 13 | calculateTransactionFee, 14 | } = require('@ethereansos/multiverse'); 15 | 16 | const TIME_SLOTS_IN_SECONDS = 15; 17 | 18 | const EVENTS_SIGNATURE = { 19 | TRANSFER_WITH_PARAMS : 'Transfer(uint256,address,address)', 20 | } 21 | 22 | const EVENT = { 23 | EMITTED : 'EMITTED', 24 | NOT_EMITTED : 'NOT_EMITTED', 25 | } 26 | 27 | function deployUniswapV2Router() { 28 | var uniswapV2Router = new web3.eth.Contract(web3.currentProvider.knowledgeBase.uniswapV2RouterABI, web3.currentProvider.knowledgeBase.uniswapV2RouterAddress); 29 | assert.notStrictEqual(uniswapV2Router, undefined); 30 | return uniswapV2Router; 31 | } 32 | 33 | function deployUniswapV2Factory() { 34 | var uniswapV2Factory = new web3.eth.Contract(web3.currentProvider.knowledgeBase.uniswapV2FactoryABI, web3.currentProvider.knowledgeBase.uniswapV2FactoryAddress); 35 | assert.notStrictEqual(uniswapV2Factory, undefined); 36 | return uniswapV2Factory; 37 | } 38 | 39 | async function deployWethTokenWithUniswapV2(uniswapRouter) { 40 | var wethToken = new web3.eth.Contract(web3.currentProvider.knowledgeBase.IERC20ABI, await blockchainCall(uniswapRouter.methods.WETH)); 41 | assert.notStrictEqual(wethToken, undefined); 42 | assert.notStrictEqual(wethToken, VOID_ETHEREUM_ADDRESS); 43 | return wethToken; 44 | } 45 | 46 | function deployWethToken(univ3PoolAddress) { 47 | var uniswapV3Pool = new web3.eth.Contract(web3.currentProvider.knowledgeBase.UniswapV3PoolABI, univ3PoolAddress); 48 | assert.notStrictEqual(uniswapV3Pool, undefined); 49 | return uniswapV3Pool; 50 | } 51 | 52 | function deploySwapRouter() { 53 | var swapRouter = new web3.eth.Contract(web3.currentProvider.knowledgeBase.swapRouterABI, web3.currentProvider.knowledgeBase.swapRouterAddress); 54 | assert.notStrictEqual(swapRouter, undefined); 55 | return swapRouter; 56 | } 57 | 58 | function deployEthItemOrchestrator() { 59 | var ethItemOrchestrator = new web3.eth.Contract(web3.currentProvider.knowledgeBase.ethItemOrchestratorABI, web3.currentProvider.knowledgeBase.ethItemOrchestratorAddress); 60 | assert.notStrictEqual(ethItemOrchestrator, undefined); 61 | return ethItemOrchestrator; 62 | } 63 | 64 | function deployUniswapV3Pool(univ3PoolAddress) { 65 | var uniswapV3Pool = new web3.eth.Contract(web3.currentProvider.knowledgeBase.UniswapV3PoolABI, univ3PoolAddress); 66 | assert.notStrictEqual(uniswapV3Pool, undefined); 67 | return uniswapV3Pool; 68 | } 69 | 70 | function printContractABI(contract) { 71 | console.log("* " + contract.name + " ABI *"); 72 | console.log(contract.abi); 73 | console.log("°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°"); 74 | } 75 | 76 | async function compileFixedInflationContract(filename, subfolders) { 77 | var subpath = subfolders != null ? subfolders + "/" : ""; 78 | var path = "fixed-inflation/" + subpath + filename; 79 | const contract = await compile(path); 80 | return contract; 81 | } 82 | 83 | async function compileFarmingContract(filename, subfolders) { 84 | var subpath = subfolders != null ? subfolders + "/" : ""; 85 | const contract = await compile("farming/" + subpath + filename); 86 | return contract; 87 | } 88 | 89 | async function compileAmmAggregatorContract(filename, subfolders) { 90 | var subpath = subfolders != null ? subfolders + "/" : ""; 91 | const contract = await compile("amm-aggregator/" + subpath + filename); 92 | return contract; 93 | } 94 | 95 | async function compileAmmAggregatorContractImpl(filename) { 96 | const contract = await compile("amm-aggregator/impl/" + filename); 97 | return contract; 98 | } 99 | 100 | 101 | function numberToString(num, locale) { 102 | if (num === undefined || num === null) { 103 | num = 0; 104 | } 105 | if ((typeof num).toLowerCase() === 'string') { 106 | return num.split(',').join(''); 107 | } 108 | let numStr = String(num); 109 | 110 | if (Math.abs(num) < 1.0) { 111 | let e = parseInt(num.toString().split('e-')[1]); 112 | if (e) { 113 | let negative = num < 0; 114 | if (negative) num *= -1 115 | num *= Math.pow(10, e - 1); 116 | numStr = '0.' + (new Array(e)).join('0') + num.toString().substring(2); 117 | if (negative) numStr = "-" + numStr; 118 | } 119 | } else { 120 | let e = parseInt(num.toString().split('+')[1]); 121 | if (e > 20) { 122 | e -= 20; 123 | num /= Math.pow(10, e); 124 | numStr = num.toString() + (new Array(e + 1)).join('0'); 125 | } 126 | } 127 | if (locale === true) { 128 | var numStringSplitted = numStr.split(' ').join('').split('.'); 129 | return parseInt(numStringSplitted[0]).toLocaleString() + (numStringSplitted.length === 1 ? '' : (Utils.decimalsSeparator + numStringSplitted[1])) 130 | } 131 | return numStr; 132 | } 133 | 134 | 135 | 136 | 137 | module.exports = { 138 | EVENTS_SIGNATURE, 139 | EVENT, 140 | TIME_SLOTS_IN_SECONDS, 141 | compileAmmAggregatorContract, 142 | compileAmmAggregatorContractImpl, 143 | compileFixedInflationContract, 144 | compileFarmingContract, 145 | deployEthItemOrchestrator, 146 | deploySwapRouter, 147 | deployUniswapV2Factory, 148 | deployUniswapV2Router, 149 | deployUniswapV3Pool, 150 | deployWethTokenWithUniswapV2, 151 | numberToString, 152 | printContractABI, 153 | }; -------------------------------------------------------------------------------- /procedures/routines/index.js: -------------------------------------------------------------------------------- 1 | var { 2 | VOID_ETHEREUM_ADDRESS, 3 | VOID_BYTES32, 4 | blockchainCall, 5 | compile, 6 | deployContract, 7 | abi, 8 | MAX_UINT256, 9 | web3Utils, 10 | fromDecimals, 11 | toDecimals, 12 | sendBlockchainTransaction, 13 | calculateTransactionFee, 14 | } = require('@ethereansos/multiverse'); 15 | var buildOSStuff = require('../../resources/OS/buildOsStuff'); 16 | var fs = require('fs'); 17 | var misc = require("../misc"); 18 | var path = require('path'); 19 | 20 | var deployDFOAndFactoryDone = false; 21 | 22 | var ethItemOrchestrator; 23 | var uniswapV2Factory; 24 | var uniswapV2Router; 25 | var wethToken; 26 | 27 | var rewardToken; 28 | var mainToken; 29 | var secondaryToken; 30 | 31 | var ethToSpend = 600000; 32 | 33 | var UniswapV2AMMV1; 34 | var uniswapAMMV2; 35 | var uniswapAMM; 36 | 37 | var FixedInflationFactory; 38 | var fixedInflationFactory; 39 | 40 | var FixedInflationExtension; 41 | var fixedInflationExtension; 42 | 43 | var DFOBasedFixedInflationExtensionFactory; 44 | var DFOBasedFixedInflationExtension; 45 | 46 | var FixedInflation; 47 | var fixedInflation; 48 | 49 | var FixedInflationDefaultExtension; 50 | var fixedInflationDefaultExtension; 51 | 52 | var liquidityPool; 53 | 54 | var dFOBasedFixedInflationExtensionFactory; 55 | 56 | var tokens; 57 | 58 | var actors = {}; 59 | 60 | async function compileContracts() { 61 | FixedInflationFactory = await misc.compileFixedInflationContract("FixedInflationFactory", null); 62 | console.log("FixedInflationFactory done..."); 63 | FixedInflationDefaultExtension = await misc.compileFixedInflationContract("FixedInflationExtension", null); 64 | console.log("FixedInflationExtension done..."); 65 | FixedInflation = await compile('fixed-inflation/FixedInflationUniV3'); 66 | console.log("FixedInflationUniV3 done..."); 67 | 68 | FixedInflationExtension = await misc.compileFixedInflationContract("DFOBasedFixedInflationExtension", "dfo"); 69 | DFOBasedFixedInflationExtensionFactory = await misc.compileFixedInflationContract("DFOBasedFixedInflationExtensionFactory", "dfo"); 70 | DFOBasedFixedInflationExtension = await misc.compileFixedInflationContract("DFOBasedFixedInflationExtension", "dfo"); 71 | 72 | UniswapV2AMMV1 = await misc.compileAmmAggregatorContract("UniswapV2AMMV1", "models/UniswapV2/1"); 73 | 74 | uniswapAMM = await deployContract(new web3.eth.Contract(UniswapV2AMMV1.abi), UniswapV2AMMV1.bin, [uniswapV2Router.options.address]); 75 | uniswapAMMV2 = uniswapAMM; 76 | 77 | tokens = [ 78 | web3.currentProvider.knowledgeBase.wethTokenAddress, 79 | web3.currentProvider.knowledgeBase.usdtTokenAddress, 80 | web3.currentProvider.knowledgeBase.chainLinkTokenAddress, 81 | web3.currentProvider.knowledgeBase.usdcTokenAddress, 82 | web3.currentProvider.knowledgeBase.daiTokenAddress, 83 | web3.currentProvider.knowledgeBase.mkrTokenAddress, 84 | web3.currentProvider.knowledgeBase.buidlTokenAddress, 85 | web3.currentProvider.knowledgeBase.balTokenAddress, 86 | web3.currentProvider.knowledgeBase.osTokenAddress 87 | ].map(it => new web3.eth.Contract(web3.currentProvider.knowledgeBase.IERC20ABI, it)); 88 | 89 | await Promise.all(tokens.map(it => misc.buyForETH(it, ethToSpend, null, uniswapAMM))); 90 | 91 | UniswapV3AMMV1 = await compile('amm-aggregator/models/UniswapV3/1/UniswapV3AMMV1'); 92 | 93 | uniswapAMM = await deployContract(new web3.eth.Contract(UniswapV3AMMV1.abi), UniswapV3AMMV1.bin, 94 | [ 95 | web3.currentProvider.knowledgeBase.swapRouterAddress, 96 | web3.currentProvider.knowledgeBase.uniswapV3NonfungiblePositionManagerAddress, 97 | web3.currentProvider.knowledgeBase.uniswapV3QuoterAddress, 98 | "0.00001".toDecimals(18) 99 | ] 100 | ); 101 | await buyForETH(tokens[tokens.length - 1], ethToSpend, null, uniswapAMM); 102 | 103 | } 104 | 105 | 106 | async function deployDFOAndFactory() { 107 | if (deployDFOAndFactoryDone) { 108 | return; 109 | } 110 | deployDFOAndFactoryDone = true; 111 | 112 | var fixedInflationModel = await deployContract(new web3.eth.Contract(FixedInflation.abi), FixedInflation.bin); 113 | 114 | var fixedInflationModel = await deployContract(new web3.eth.Contract(FixedInflationDefaultExtension.abi), FixedInflationDefaultExtension.bin); 115 | 116 | fixedInflationModel = await deployContract(new web3.eth.Contract(FixedInflationFactory.abi), FixedInflationFactory.bin, 117 | [ 118 | VOID_ETHEREUM_ADDRESS, 119 | fixedInflationModel.options.address, 120 | fixedInflationDefaultExtensionModel.options.address, 121 | toDecimals("0.1", 18) 122 | ] 123 | ); 124 | 125 | 126 | // FIXME 127 | // await sendBlockchainTransaction( 128 | // web3.currentProvider, 129 | // accounts[0], 130 | // web3.currentProvider.knowledgeBase.wethTokenAddress, 131 | // web3.utils.sha3("deposit()").substring(0, 10), 132 | // toDecimals(30, 18) 133 | // ); 134 | 135 | // await web3.eth.sendTransaction(blockchainConnection.getSendingOptions({ 136 | // to: dfo.mvdWalletAddress, 137 | // value: utilities.toDecimals(30, 18) 138 | // })); 139 | 140 | for (var token of tokens) { 141 | try { 142 | await token.methods.transfer(dfo.mvdWalletAddress, utilities.toDecimals(1000, await token.methods.decimals().call())).send(blockchainConnection.getSendingOptions()); 143 | } catch (e) { 144 | var value = utilities.toDecimals(15, await token.methods.decimals().call()); 145 | var balance = await token.methods.balanceOf(accounts[0]).call(); 146 | value = parseInt(value) > parseInt(balance) ? utilities.numberToString(parseInt(parseInt(balance) * 0.8)) : value; 147 | await token.methods.transfer(dfo.mvdWalletAddress, value).send(blockchainConnection.getSendingOptions()); 148 | } 149 | } 150 | 151 | await dfo.votingToken.methods.transfer(dfo.mvdWalletAddress, utilities.toDecimals(300000, await dfo.votingToken.methods.decimals().call())).send(blockchainConnection.getSendingOptions()); 152 | } 153 | 154 | module.exports = async function run() { 155 | console.log("==========================================================="); 156 | console.log("* MULTIVERSE - run() - started *"); 157 | 158 | console.log(""); 159 | console.group("Initializing the environment..."); 160 | console.log("Creating contracts objects..."); 161 | ethItemOrchestrator = misc.deployEthItemOrchestrator(); 162 | uniswapV2Router = misc.deployUniswapV2Router(); 163 | uniswapV2Factory = misc.deployUniswapV2Factory(); 164 | console.groupEnd(); 165 | console.log(""); 166 | 167 | console.group("Preparing contracts..."); 168 | console.log("Compiling..."); 169 | await compileContracts(); 170 | console.groupEnd(); 171 | console.log(""); 172 | 173 | console.group("Deploying DFO and Factory, then deploying all occurency stuff..."); 174 | console.log("Compiling..."); 175 | await deployDFOAndFactory().then(deployAllOccurencyStuff); 176 | console.groupEnd(); 177 | console.log(""); 178 | 179 | 180 | 181 | console.log("* MULTIVERSE - run() - finished *"); 182 | console.log("==========================================================="); 183 | }; 184 | 185 | 186 | 187 | 188 | 189 | module.exports.test = async function test() { 190 | console.log("* MULTIVERSE - test() started *"); 191 | console.log("* MULTIVERSE - test() - finished *"); 192 | }; -------------------------------------------------------------------------------- /resources/OS/OSFarmingExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../../contracts/farming/impl/FarmingGen1Extension.sol"; 6 | 7 | contract OSFarmingExtension is FarmingGen1Extension { 8 | 9 | address public osMinterAddress; 10 | 11 | function init(bool byMint, address host, address treasury, address _osMinterAddress) public { 12 | super.init(byMint, host, treasury); 13 | osMinterAddress = _osMinterAddress; 14 | } 15 | 16 | function init(bool, address, address) public virtual override { 17 | revert("use specific method if not already init"); 18 | } 19 | 20 | function _mintAndTransfer(address, address recipient, uint256 value) internal override { 21 | IERC20Mintable(osMinterAddress).mint(recipient, value); 22 | } 23 | } -------------------------------------------------------------------------------- /resources/OS/OSRoutinesExtension.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.7.0; 3 | pragma abicoder v2; 4 | 5 | import "../../contracts/routines/impl/RoutinesExtension.sol"; 6 | 7 | contract OSRoutinesExtension is RoutinesExtension { 8 | 9 | address public osMinterAddress; 10 | 11 | function init(address host, address _osMinterAddress) public { 12 | super.init(host); 13 | osMinterAddress = _osMinterAddress; 14 | } 15 | 16 | function init(address) public override { 17 | revert("use specific method if not already init"); 18 | } 19 | 20 | function _mintAndTransfer(address, address recipient, uint256 value) internal override { 21 | IERC20Mintable(osMinterAddress).mint(recipient, value); 22 | } 23 | } -------------------------------------------------------------------------------- /test/multiverse-procedures.js: -------------------------------------------------------------------------------- 1 | describe("Multiverse", () => it("Procedures", require("@ethereansos/multiverse/environments/runner"))); --------------------------------------------------------------------------------