├── .gitattributes ├── contracts ├── OpenZeppelin │ ├── GSN │ │ └── Context.sol │ ├── math │ │ ├── Math.sol │ │ └── SignedSafeMath.sol │ ├── utils │ │ ├── Context.sol │ │ ├── Strings.sol │ │ ├── Arrays.sol │ │ ├── Counters.sol │ │ ├── Pausable.sol │ │ └── ReentrancyGuard.sol │ ├── token │ │ └── ERC20 │ │ │ ├── TokenTimelock.sol │ │ │ ├── README.adoc │ │ │ └── SafeERC20.sol │ └── access │ │ └── Ownable.sol ├── interfaces │ ├── IMisoFermenter.sol │ ├── IMisoTemplate.sol │ ├── IMisoTokenFactory.sol │ ├── IMisoFarm.sol │ ├── IMisoToken.sol │ ├── IGnosisProxyFactory.sol │ ├── IWETH9.sol │ ├── IMisoMarket.sol │ ├── IMisoLiquidity.sol │ ├── IRewarder.sol │ ├── IMasterContract.sol │ ├── IMisoCrowdsale.sol │ ├── IMisoLauncher.sol │ ├── IBentoBoxFactory.sol │ ├── IWhiteList.sol │ ├── IPointList.sol │ ├── ISafeGnosis.sol │ ├── IERC20.sol │ ├── ISushiToken.sol │ ├── IMisoAuction.sol │ └── IMasterChef.sol ├── UniswapV2 │ ├── interfaces │ │ ├── IUniswapV2Callee.sol │ │ ├── IWETH.sol │ │ ├── IERC20.sol │ │ ├── IUniswapV2Factory.sol │ │ ├── IUniswapV2ERC20.sol │ │ ├── IUniswapV2Router02.sol │ │ ├── IUniswapV2Pair.sol │ │ └── IUniswapV2Router01.sol │ ├── README.md │ ├── libraries │ │ ├── SafeMath.sol │ │ ├── UQ112x112.sol │ │ ├── Math.sol │ │ └── TransferHelper.sol │ ├── UniswapV2Factory.sol │ ├── UniswapV2ERC20.sol │ └── UniswapV2Library.sol ├── Tokens │ ├── ERC20 │ │ ├── ERC20Pausable.sol │ │ └── ERC20Burnable.sol │ ├── FixedToken.sol │ └── MintableToken.sol ├── Utils │ ├── Owned.sol │ ├── BoringOwnable.sol │ ├── SafeMathPlus.sol │ ├── BoringFactory.sol │ ├── CloneFactory.sol │ ├── WETH9.sol │ ├── BoringBatchable.sol │ ├── BoringMath.sol │ ├── BoringERC20.sol │ ├── SafeTransfer.sol │ └── Documents.sol ├── Access │ ├── TokenList.sol │ ├── MISOAdminAccess.sol │ ├── PointList.sol │ ├── MISOAccessFactory.sol │ └── MISOAccessControls.sol ├── Vault │ ├── GnosisSafeFactory.sol │ └── TokenVault.sol └── Recipes │ └── MISORecipe03.vy ├── interfaces ├── IMisoFermenter.sol ├── IMisoTemplate.sol ├── IMisoTokenFactory.sol ├── IMisoFarm.sol ├── IMisoToken.sol ├── IGnosisProxyFactory.sol ├── IWETH9.sol ├── IMisoMarket.sol ├── IMisoLiquidity.sol ├── IRewarder.sol ├── IMasterContract.sol ├── IMisoCrowdsale.sol ├── IMisoLauncher.sol ├── IBentoBoxFactory.sol ├── IWhiteList.sol ├── IPointList.sol ├── ISafeGnosis.sol ├── IERC20.sol ├── ISushiToken.sol ├── IMisoAuction.sol └── IMasterChef.sol ├── slither └── slither.config.json ├── tests ├── __pycache__ │ ├── settings.cpython-38.pyc │ ├── conftest.cpython-38-pytest-6.0.1.pyc │ ├── test_crowdsale.cpython-38-pytest-6.0.1.pyc │ ├── test_launcher.cpython-38-pytest-6.0.1.pyc │ ├── test_fixed_token.cpython-38-pytest-6.0.1.pyc │ ├── test_dutch_auction.cpython-38-pytest-6.0.1.pyc │ ├── test_mintable_token.cpython-38-pytest-6.0.1.pyc │ ├── test_token_factory.cpython-38-pytest-6.0.1.pyc │ └── test_auction_factory.cpython-38-pytest-6.0.1.pyc ├── test_fixed_token.py ├── test_mintable_token.py ├── settings.py ├── test_auction_factory.py ├── test_access_control.py ├── test_master_chef.py ├── test_point_list.py └── test_token_lock.py ├── README.md ├── spec ├── harness │ ├── Wallet.sol │ ├── Receiver.sol │ ├── MISOAccessControls.sol │ ├── Documents.sol │ ├── DummyERC20A.sol │ ├── DummyERC20B.sol │ ├── SafeTransfer.sol │ ├── DummyWeth.sol │ └── DutchAuctionHarness.sol ├── scripts │ ├── runDutchAuctionPriceFunctions.sh │ ├── runDutchAuction.sh │ ├── runDutchAuctionAdditional.sh │ ├── runRule.sh │ └── applyHarness.sh ├── dutchAuctionCurrentPrice.spec └── dutchAuctionAdditional.spec ├── scripts ├── get_gnosis_safe.py ├── settings.py ├── deploy_AddTokenTemplate.py ├── deploy_auction.py ├── verify.py ├── deploy_gnosis.py ├── deploy_MISO.py ├── deploy_recipe02.py └── deploy_MISO_dev.py ├── brownie-config.yaml └── .gitignore /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | *.vy linguist-language=Python 3 | -------------------------------------------------------------------------------- /contracts/OpenZeppelin/GSN/Context.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "../utils/Context.sol"; 6 | -------------------------------------------------------------------------------- /interfaces/IMisoFermenter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoFermenter { 4 | function initERC20Vault() external; 5 | } -------------------------------------------------------------------------------- /slither/slither.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "filter_paths": "openzeppelin|console.sol|Migrations.sol", 3 | "json": "security.json" 4 | } 5 | -------------------------------------------------------------------------------- /tests/__pycache__/settings.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/settings.cpython-38.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MISO 2 | ## Minimal Initial SushiSwap Offering 3 | 4 | A smart contract factory for creating new tokens and listing on SushiSwap. -------------------------------------------------------------------------------- /contracts/interfaces/IMisoFermenter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoFermenter { 4 | function initERC20Vault() external; 5 | } -------------------------------------------------------------------------------- /tests/__pycache__/conftest.cpython-38-pytest-6.0.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/conftest.cpython-38-pytest-6.0.1.pyc -------------------------------------------------------------------------------- /interfaces/IMisoTemplate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoTemplate { 4 | function initData( 5 | bytes calldata data 6 | ) external; 7 | } -------------------------------------------------------------------------------- /tests/__pycache__/test_crowdsale.cpython-38-pytest-6.0.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/test_crowdsale.cpython-38-pytest-6.0.1.pyc -------------------------------------------------------------------------------- /tests/__pycache__/test_launcher.cpython-38-pytest-6.0.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/test_launcher.cpython-38-pytest-6.0.1.pyc -------------------------------------------------------------------------------- /tests/__pycache__/test_fixed_token.cpython-38-pytest-6.0.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/test_fixed_token.cpython-38-pytest-6.0.1.pyc -------------------------------------------------------------------------------- /contracts/interfaces/IMisoTemplate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoTemplate { 4 | function initData( 5 | bytes calldata data 6 | ) external; 7 | } -------------------------------------------------------------------------------- /tests/__pycache__/test_dutch_auction.cpython-38-pytest-6.0.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/test_dutch_auction.cpython-38-pytest-6.0.1.pyc -------------------------------------------------------------------------------- /tests/__pycache__/test_mintable_token.cpython-38-pytest-6.0.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/test_mintable_token.cpython-38-pytest-6.0.1.pyc -------------------------------------------------------------------------------- /tests/__pycache__/test_token_factory.cpython-38-pytest-6.0.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/test_token_factory.cpython-38-pytest-6.0.1.pyc -------------------------------------------------------------------------------- /tests/__pycache__/test_auction_factory.cpython-38-pytest-6.0.1.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chefgonpachi/MISO/HEAD/tests/__pycache__/test_auction_factory.cpython-38-pytest-6.0.1.pyc -------------------------------------------------------------------------------- /contracts/UniswapV2/interfaces/IUniswapV2Callee.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IUniswapV2Callee { 4 | function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external; 5 | } 6 | -------------------------------------------------------------------------------- /interfaces/IMisoTokenFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoTokenFactory { 4 | function numberOfTokens() external view returns (uint256); 5 | function getTokens() external view returns (address[] memory); 6 | } -------------------------------------------------------------------------------- /spec/harness/Wallet.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | contract Wallet { 4 | fallback() external payable { } 5 | 6 | function sendTo() external payable returns (bool) { return true; } 7 | 8 | receive() external payable { } 9 | } -------------------------------------------------------------------------------- /contracts/interfaces/IMisoTokenFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoTokenFactory { 4 | function numberOfTokens() external view returns (uint256); 5 | function getTokens() external view returns (address[] memory); 6 | } -------------------------------------------------------------------------------- /interfaces/IMisoFarm.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoFarm { 4 | 5 | function initFarm( 6 | bytes calldata data 7 | ) external; 8 | function farmTemplate() external view returns (uint256); 9 | 10 | } -------------------------------------------------------------------------------- /spec/harness/Receiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | contract Receiver { 4 | fallback() external payable { } 5 | 6 | function sendTo() external payable returns (bool) { return true; } 7 | 8 | receive() external payable { } 9 | } -------------------------------------------------------------------------------- /contracts/UniswapV2/interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IWETH { 4 | function deposit() external payable; 5 | function transfer(address to, uint value) external returns (bool); 6 | function withdraw(uint) external; 7 | } -------------------------------------------------------------------------------- /contracts/interfaces/IMisoFarm.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoFarm { 4 | 5 | function initFarm( 6 | bytes calldata data 7 | ) external; 8 | function farmTemplate() external view returns (uint256); 9 | 10 | } -------------------------------------------------------------------------------- /interfaces/IMisoToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoToken { 4 | function init(bytes calldata data) external payable; 5 | function initToken( bytes calldata data ) external; 6 | function tokenTemplate() external view returns (uint256); 7 | 8 | } -------------------------------------------------------------------------------- /contracts/interfaces/IMisoToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoToken { 4 | function init(bytes calldata data) external payable; 5 | function initToken( bytes calldata data ) external; 6 | function tokenTemplate() external view returns (uint256); 7 | 8 | } -------------------------------------------------------------------------------- /interfaces/IGnosisProxyFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | import "./ISafeGnosis.sol"; 3 | interface IGnosisProxyFactory { 4 | function createProxy( 5 | ISafeGnosis masterCopy, bytes memory data) external returns(ISafeGnosis proxy); 6 | 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /interfaces/IWETH9.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "./IERC20.sol"; 4 | 5 | interface IWETH is IERC20 { 6 | function deposit() external payable; 7 | function withdraw(uint) external; 8 | function transfer(address, uint) external returns (bool); 9 | 10 | } -------------------------------------------------------------------------------- /contracts/interfaces/IGnosisProxyFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | import "./ISafeGnosis.sol"; 3 | interface IGnosisProxyFactory { 4 | function createProxy( 5 | ISafeGnosis masterCopy, bytes memory data) external returns(ISafeGnosis proxy); 6 | 7 | 8 | } 9 | 10 | -------------------------------------------------------------------------------- /contracts/interfaces/IWETH9.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "./IERC20.sol"; 4 | 5 | interface IWETH is IERC20 { 6 | function deposit() external payable; 7 | function withdraw(uint) external; 8 | function transfer(address, uint) external returns (bool); 9 | 10 | } -------------------------------------------------------------------------------- /interfaces/IMisoMarket.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoMarket { 4 | 5 | function init(bytes calldata data) external payable; 6 | function initMarket( bytes calldata data ) external; 7 | function marketTemplate() external view returns (uint256); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /contracts/interfaces/IMisoMarket.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoMarket { 4 | 5 | function init(bytes calldata data) external payable; 6 | function initMarket( bytes calldata data ) external; 7 | function marketTemplate() external view returns (uint256); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /spec/scripts/runDutchAuctionPriceFunctions.sh: -------------------------------------------------------------------------------- 1 | certoraRun contracts/Auctions/DutchAuction.sol \ 2 | --verify DutchAuction:spec/dutchAuctionCurrentPrice.spec \ 3 | --solc solc6.12 \ 4 | --cache dutchAuctionPrice \ 5 | --settings -assumeUnwindCond \ 6 | --cloud --msg "dutch auction price function : all rules" -------------------------------------------------------------------------------- /interfaces/IMisoLiquidity.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoLiquidity { 4 | function initLauncher( 5 | bytes calldata data 6 | ) external; 7 | 8 | function getMarkets() external view returns(address[] memory); 9 | function liquidityTemplate() external view returns (uint256); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/interfaces/IMisoLiquidity.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoLiquidity { 4 | function initLauncher( 5 | bytes calldata data 6 | ) external; 7 | 8 | function getMarkets() external view returns(address[] memory); 9 | function liquidityTemplate() external view returns (uint256); 10 | } 11 | -------------------------------------------------------------------------------- /scripts/get_gnosis_safe.py: -------------------------------------------------------------------------------- 1 | from brownie import * 2 | from .settings import * 3 | from .contracts import * 4 | from .contract_addresses import * 5 | import time 6 | 7 | 8 | def main(): 9 | load_accounts() 10 | gnosis_vault = GnosisVault.at( 11 | CONTRACTS[network.show_active()]["gnosis_vault"]) 12 | print(gnosis_vault.proxy()) 13 | -------------------------------------------------------------------------------- /contracts/interfaces/IRewarder.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "../Utils/BoringERC20.sol"; 4 | 5 | interface IRewarder { 6 | using BoringERC20 for IERC20; 7 | function onSushiReward (uint256 pid, address user, uint256 sushiAmount) external; 8 | function pendingTokens(uint256 pid, address user, uint256 sushiAmount) external returns (IERC20[] memory , uint256[] memory); 9 | } -------------------------------------------------------------------------------- /interfaces/IRewarder.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "../contracts/Utils/BoringERC20.sol"; 4 | 5 | interface IRewarder { 6 | using BoringERC20 for IERC20; 7 | function onSushiReward (uint256 pid, address user, uint256 sushiAmount) external; 8 | function pendingTokens(uint256 pid, address user, uint256 sushiAmount) external returns (IERC20[] memory , uint256[] memory); 9 | } -------------------------------------------------------------------------------- /interfaces/IMasterContract.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMasterContract { 4 | /// @notice Init function that gets called from `BoringFactory.deploy`. 5 | /// Also kown as the constructor for cloned contracts. 6 | /// Any ETH send to `BoringFactory.deploy` ends up here. 7 | /// @param data Can be abi encoded arguments or anything else. 8 | function init(bytes calldata data) external payable; 9 | } -------------------------------------------------------------------------------- /contracts/interfaces/IMasterContract.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMasterContract { 4 | /// @notice Init function that gets called from `BoringFactory.deploy`. 5 | /// Also kown as the constructor for cloned contracts. 6 | /// Any ETH send to `BoringFactory.deploy` ends up here. 7 | /// @param data Can be abi encoded arguments or anything else. 8 | function init(bytes calldata data) external payable; 9 | } -------------------------------------------------------------------------------- /interfaces/IMisoCrowdsale.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoCrowdsale { 4 | function initCrowdsale( 5 | address _funder, 6 | address _token, 7 | address _paymentCurrency, 8 | uint256 _tokenSupply, 9 | uint256 _startDate, 10 | uint256 _endDate, 11 | uint256 _rate, 12 | uint256 _goal, 13 | address _operator, 14 | address payable _wallet 15 | ) external; 16 | } 17 | -------------------------------------------------------------------------------- /interfaces/IMisoLauncher.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoLauncher { 4 | function createLauncher( 5 | uint256 _templateId, 6 | address _token, 7 | uint256 _tokenSupply, 8 | address payable _integratorFeeAccount, 9 | bytes calldata _data 10 | ) 11 | external payable returns (address newLauncher); 12 | 13 | function currentTemplateId(uint256 tempalateType) external returns (uint256); 14 | } -------------------------------------------------------------------------------- /contracts/interfaces/IMisoCrowdsale.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoCrowdsale { 4 | function initCrowdsale( 5 | address _funder, 6 | address _token, 7 | address _paymentCurrency, 8 | uint256 _tokenSupply, 9 | uint256 _startDate, 10 | uint256 _endDate, 11 | uint256 _rate, 12 | uint256 _goal, 13 | address _operator, 14 | address payable _wallet 15 | ) external; 16 | } 17 | -------------------------------------------------------------------------------- /contracts/interfaces/IMisoLauncher.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoLauncher { 4 | function createLauncher( 5 | uint256 _templateId, 6 | address _token, 7 | uint256 _tokenSupply, 8 | address payable _integratorFeeAccount, 9 | bytes calldata _data 10 | ) 11 | external payable returns (address newLauncher); 12 | 13 | function currentTemplateId(uint256 tempalateType) external returns (uint256); 14 | } -------------------------------------------------------------------------------- /spec/scripts/runDutchAuction.sh: -------------------------------------------------------------------------------- 1 | certoraRun spec/harness/DutchAuctionHarness.sol spec/harness/DummyERC20A.sol \ 2 | spec/harness/DummyERC20B.sol spec/harness/DummyWeth.sol spec/harness/Receiver.sol spec/harness/Wallet.sol:Wallet \ 3 | --verify DutchAuctionHarness:spec/dutchAuction.spec \ 4 | --link DutchAuctionHarness:wallet=Wallet \ 5 | --settings -assumeUnwindCond,-ignoreViewFunctions,-enableStorageAnalysis=true,-depth=15 \ 6 | --solc solc6.12 \ 7 | --cloud --msg "dutch auction : all rules" -------------------------------------------------------------------------------- /spec/scripts/runDutchAuctionAdditional.sh: -------------------------------------------------------------------------------- 1 | certoraRun spec/harness/DutchAuctionHarness.sol spec/harness/DummyERC20A.sol \ 2 | spec/harness/DummyERC20B.sol spec/harness/DummyWeth.sol spec/harness/Receiver.sol spec/harness/Wallet.sol:Wallet \ 3 | --verify DutchAuctionHarness:spec/dutchAuctionAdditional.spec \ 4 | --link DutchAuctionHarness:wallet=Wallet \ 5 | --settings -assumeUnwindCond,-ignoreViewFunctions,-enableStorageAnalysis=true,-depth=15 \ 6 | --solc solc6.12 \ 7 | --cloud --msg "dutch auction : additional rules" -------------------------------------------------------------------------------- /interfaces/IBentoBoxFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IBentoBoxFactory { 4 | function deploy(address masterContract, bytes calldata data, bool useCreate2) external payable returns (address cloneAddress) ; 5 | function masterContractApproved(address, address) external view returns (bool); 6 | function masterContractOf(address) external view returns (address); 7 | function setMasterContractApproval(address user, address masterContract, bool approved, uint8 v, bytes32 r, bytes32 s) external; 8 | } -------------------------------------------------------------------------------- /contracts/interfaces/IBentoBoxFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IBentoBoxFactory { 4 | function deploy(address masterContract, bytes calldata data, bool useCreate2) external payable returns (address cloneAddress) ; 5 | function masterContractApproved(address, address) external view returns (bool); 6 | function masterContractOf(address) external view returns (address); 7 | function setMasterContractApproval(address user, address masterContract, bool approved, uint8 v, bytes32 r, bytes32 s) external; 8 | } -------------------------------------------------------------------------------- /interfaces/IWhiteList.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | // ---------------------------------------------------------------------------- 4 | // White List interface 5 | // ---------------------------------------------------------------------------- 6 | 7 | interface IWhiteList { 8 | function isInWhiteList(address account) external view returns (bool); 9 | function addWhiteList(address[] calldata accounts) external ; 10 | function removeWhiteList(address[] calldata accounts) external ; 11 | function initWhiteList(address accessControl) external ; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /contracts/interfaces/IWhiteList.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | // ---------------------------------------------------------------------------- 4 | // White List interface 5 | // ---------------------------------------------------------------------------- 6 | 7 | interface IWhiteList { 8 | function isInWhiteList(address account) external view returns (bool); 9 | function addWhiteList(address[] calldata accounts) external ; 10 | function removeWhiteList(address[] calldata accounts) external ; 11 | function initWhiteList(address accessControl) external ; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /contracts/UniswapV2/README.md: -------------------------------------------------------------------------------- 1 | # Uniswap V2 Area 2 | 3 | Code from [Uniswap V2](https://github.com/Uniswap/uniswap-v2-core/tree/27f6354bae6685612c182c3bc7577e61bc8717e3/contracts) with the following modifications. 4 | 5 | 1. Change contract version to 0.6.12 and do the necessary patching. 6 | 2. Add `migrator` member in `UniswapV2Factory` which can be set by `feeToSetter`. 7 | 3. Allow `migrator` to specify the amount of `liquidity` during the first mint. Disallow first mint if migrator is set. 8 | 9 | To see all diffs: 10 | 11 | ``` 12 | $ git diff 4c4bf551417e3df09a25aa0dbb6941cccbbac11a . 13 | ``` -------------------------------------------------------------------------------- /spec/scripts/runRule.sh: -------------------------------------------------------------------------------- 1 | certoraRun spec/harness/DutchAuctionHarness.sol:DutchAuctionHarness spec/harness/DummyERC20A.sol:DummyERC20A \ 2 | spec/harness/DummyERC20B.sol:DummyERC20B spec/harness/DummyWeth.sol:DummyWeth spec/harness/Receiver.sol:Receiver spec/harness/Wallet.sol:Wallet \ 3 | --verify DutchAuctionHarness:spec/dutchAuction.spec \ 4 | --link DutchAuctionHarness:wallet=Wallet \ 5 | --settings -assumeUnwindCond,-ignoreViewFunctions,-enableStorageAnalysis=true,-postProcessCounterExamples=true \ 6 | --solc solc6.12 \ 7 | --rule integrityOfTokensClaimable \ 8 | --staging alex/prettify-models --msg "dutch auction : integrityOfTokensClaimable" -------------------------------------------------------------------------------- /interfaces/IPointList.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | // ---------------------------------------------------------------------------- 4 | // White List interface 5 | // ---------------------------------------------------------------------------- 6 | 7 | interface IPointList { 8 | function isInList(address account) external view returns (bool); 9 | function hasPoints(address account, uint256 amount) external view returns (bool); 10 | function setPoints( 11 | address[] memory accounts, 12 | uint256[] memory amounts 13 | ) external; 14 | function initPointList(address accessControl) external ; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /contracts/interfaces/IPointList.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | // ---------------------------------------------------------------------------- 4 | // White List interface 5 | // ---------------------------------------------------------------------------- 6 | 7 | interface IPointList { 8 | function isInList(address account) external view returns (bool); 9 | function hasPoints(address account, uint256 amount) external view returns (bool); 10 | function setPoints( 11 | address[] memory accounts, 12 | uint256[] memory amounts 13 | ) external; 14 | function initPointList(address accessControl) external ; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /contracts/UniswapV2/libraries/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.6.12; 2 | 3 | // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) 4 | 5 | library SafeMathUniswap { 6 | function add(uint x, uint y) internal pure returns (uint z) { 7 | require((z = x + y) >= x, 'ds-math-add-overflow'); 8 | } 9 | 10 | function sub(uint x, uint y) internal pure returns (uint z) { 11 | require((z = x - y) <= x, 'ds-math-sub-underflow'); 12 | } 13 | 14 | function mul(uint x, uint y) internal pure returns (uint z) { 15 | require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/UniswapV2/libraries/UQ112x112.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.6.12; 2 | 3 | // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) 4 | 5 | // range: [0, 2**112 - 1] 6 | // resolution: 1 / 2**112 7 | 8 | library UQ112x112 { 9 | uint224 constant Q112 = 2**112; 10 | 11 | // encode a uint112 as a UQ112x112 12 | function encode(uint112 y) internal pure returns (uint224 z) { 13 | z = uint224(y) * Q112; // never overflows 14 | } 15 | 16 | // divide a UQ112x112 by a uint112, returning a UQ112x112 17 | function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { 18 | z = x / uint224(y); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/UniswapV2/libraries/Math.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.6.12; 2 | 3 | // a library for performing various math operations 4 | 5 | library MathUniswap { 6 | function min(uint x, uint y) internal pure returns (uint z) { 7 | z = x < y ? x : y; 8 | } 9 | 10 | // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) 11 | function sqrt(uint y) internal pure returns (uint z) { 12 | if (y > 3) { 13 | z = y; 14 | uint x = y / 2 + 1; 15 | while (x < z) { 16 | z = x; 17 | x = (y / x + x) / 2; 18 | } 19 | } else if (y != 0) { 20 | z = 1; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/settings.py: -------------------------------------------------------------------------------- 1 | import time 2 | from brownie import * 3 | 4 | # Custom Parameters 5 | TENPOW18 = 10 ** 18 6 | 7 | # Number of tokens you wish to auction, you must be able to transfer these 8 | AUCTION_TOKENS = 1000 * TENPOW18 9 | AUCTION_DAYS = 2 10 | # auctions start at a high price per token 11 | AUCTION_START_PRICE = 100 * TENPOW18 12 | # This is minimum reserve price per token 13 | AUCTION_RESERVE = 0.001 * TENPOW18 14 | 15 | # Calculated variables 16 | AUCTION_START = int(time.time()) + 200 # Few minutes to deploy 17 | AUCTION_END = AUCTION_START + 60 * 60 * 24 * AUCTION_DAYS 18 | 19 | # Constants 20 | SYMBOL = "TT5" 21 | NAME = "Test Token" 22 | ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' 23 | ETH_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' 24 | -------------------------------------------------------------------------------- /interfaces/ISafeGnosis.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface ISafeGnosis{ 4 | function setup( 5 | address[] calldata _owners, 6 | uint256 _threshold, 7 | address to, 8 | bytes calldata data, 9 | address fallbackHandler, 10 | address paymentToken, 11 | uint256 payment, 12 | address payable paymentReceiver 13 | ) 14 | external; 15 | 16 | function execTransaction( 17 | address to, 18 | uint256 value, 19 | bytes calldata data, 20 | //ENUM.Operation? 21 | uint256 operation, 22 | uint256 safeTxGas, 23 | uint256 baseGas, 24 | uint256 gasPrice, 25 | address gasToken, 26 | address payable refundReceiver, 27 | bytes calldata signatures 28 | ) 29 | external 30 | payable 31 | returns (bool success); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /contracts/interfaces/ISafeGnosis.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface ISafeGnosis{ 4 | function setup( 5 | address[] calldata _owners, 6 | uint256 _threshold, 7 | address to, 8 | bytes calldata data, 9 | address fallbackHandler, 10 | address paymentToken, 11 | uint256 payment, 12 | address payable paymentReceiver 13 | ) 14 | external; 15 | 16 | function execTransaction( 17 | address to, 18 | uint256 value, 19 | bytes calldata data, 20 | //ENUM.Operation? 21 | uint256 operation, 22 | uint256 safeTxGas, 23 | uint256 baseGas, 24 | uint256 gasPrice, 25 | address gasToken, 26 | address payable refundReceiver, 27 | bytes calldata signatures 28 | ) 29 | external 30 | payable 31 | returns (bool success); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /contracts/UniswapV2/interfaces/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IERC20Uniswap { 4 | event Approval(address indexed owner, address indexed spender, uint value); 5 | event Transfer(address indexed from, address indexed to, uint value); 6 | 7 | function name() external view returns (string memory); 8 | function symbol() external view returns (string memory); 9 | function decimals() external view returns (uint8); 10 | function totalSupply() external view returns (uint); 11 | function balanceOf(address owner) external view returns (uint); 12 | function allowance(address owner, address spender) external view returns (uint); 13 | 14 | function approve(address spender, uint value) external returns (bool); 15 | function transfer(address to, uint value) external returns (bool); 16 | function transferFrom(address from, address to, uint value) external returns (bool); 17 | } 18 | -------------------------------------------------------------------------------- /contracts/OpenZeppelin/math/Math.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | /** 6 | * @dev Standard math utilities missing in the Solidity language. 7 | */ 8 | library Math { 9 | /** 10 | * @dev Returns the largest of two numbers. 11 | */ 12 | function max(uint256 a, uint256 b) internal pure returns (uint256) { 13 | return a >= b ? a : b; 14 | } 15 | 16 | /** 17 | * @dev Returns the smallest of two numbers. 18 | */ 19 | function min(uint256 a, uint256 b) internal pure returns (uint256) { 20 | return a < b ? a : b; 21 | } 22 | 23 | /** 24 | * @dev Returns the average of two numbers. The result is rounded towards 25 | * zero. 26 | */ 27 | function average(uint256 a, uint256 b) internal pure returns (uint256) { 28 | // (a + b) / 2 can overflow, so we distribute 29 | return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/test_fixed_token.py: -------------------------------------------------------------------------------- 1 | from brownie import accounts, web3, Wei, reverts, chain 2 | from brownie.network.transaction import TransactionReceipt 3 | from brownie.convert import to_address 4 | import pytest 5 | from brownie import Contract 6 | 7 | # Fixed token 8 | 9 | # reset the chain after every test case 10 | @pytest.fixture(autouse=True) 11 | def isolation(fn_isolation): 12 | pass 13 | 14 | @pytest.fixture(scope='function') 15 | def init_fixed_token(fixed_token): 16 | name = "Fixed Token" 17 | symbol = "FXT" 18 | owner = accounts[0] 19 | fixed_supply = 100000 * 10 ** 18 20 | 21 | fixed_token.initToken(name, symbol, owner, fixed_supply, {'from': owner}) 22 | assert fixed_token.name() == name 23 | assert fixed_token.symbol() == symbol 24 | assert fixed_token.owner() == owner 25 | assert fixed_token.totalSupply() == fixed_supply 26 | assert fixed_token.balanceOf(owner) == fixed_supply 27 | 28 | -------------------------------------------------------------------------------- /contracts/Tokens/ERC20/ERC20Pausable.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity ^0.6.0; 4 | 5 | import "../ERC20.sol"; 6 | import "../../OpenZeppelin/utils/Pausable.sol"; 7 | 8 | /** 9 | * @dev ERC20 token with pausable token transfers, minting and burning. 10 | * 11 | * Useful for scenarios such as preventing trades until the end of an evaluation 12 | * period, or having an emergency switch for freezing all token transfers in the 13 | * event of a large bug. 14 | */ 15 | abstract contract ERC20Pausable is ERC20, Pausable { 16 | /** 17 | * @dev See {ERC20-_beforeTokenTransfer}. 18 | * 19 | * Requirements: 20 | * 21 | * - the contract must not be paused. 22 | */ 23 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { 24 | super._beforeTokenTransfer(from, to, amount); 25 | 26 | require(!paused(), "ERC20Pausable: token transfer while paused"); 27 | } 28 | } -------------------------------------------------------------------------------- /contracts/UniswapV2/interfaces/IUniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IUniswapV2Factory { 4 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 5 | 6 | function feeTo() external view returns (address); 7 | function feeToSetter() external view returns (address); 8 | function migrator() external view returns (address); 9 | 10 | function getPair(address tokenA, address tokenB) external view returns (address pair); 11 | function allPairs(uint) external view returns (address pair); 12 | function allPairsLength() external view returns (uint); 13 | 14 | function pairCodeHash() external pure returns (bytes32); 15 | 16 | 17 | function createPair(address tokenA, address tokenB) external returns (address pair); 18 | 19 | function setFeeTo(address) external; 20 | function setFeeToSetter(address) external; 21 | function setMigrator(address) external; 22 | } 23 | -------------------------------------------------------------------------------- /spec/harness/MISOAccessControls.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | pragma experimental ABIEncoderV2; 3 | 4 | /* 5 | * Harness to simplify: 6 | * 1. contracts/Access/MISOAdminAccess.sol 7 | * 2. contracts/Access/MISOAccessControls.sol 8 | */ 9 | contract MISOAccessControls { 10 | bool initialized; 11 | address admin; 12 | 13 | function initAccessControls(address _admin) public { 14 | require(!initialized); 15 | initialized = true; 16 | admin = _admin; 17 | } 18 | 19 | function isInitialized() public returns (bool) { 20 | return initialized; 21 | } 22 | 23 | function hasAdminRole(address _address) public view returns (bool) { 24 | return admin == _address; 25 | } 26 | 27 | mapping (address => bool) hasRoleSMART_CONTRACT_ROLE; 28 | function hasSmartContractRole(address _address) public view returns (bool) { 29 | return hasRoleSMART_CONTRACT_ROLE[_address]; 30 | } 31 | } -------------------------------------------------------------------------------- /interfaces/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IERC20 { 4 | function totalSupply() external view returns (uint256); 5 | function balanceOf(address account) external view returns (uint256); 6 | function allowance(address owner, address spender) external view returns (uint256); 7 | function approve(address spender, uint256 amount) external returns (bool); 8 | function name() external view returns (string memory); 9 | function symbol() external view returns (string memory); 10 | function decimals() external view returns (uint8); 11 | 12 | event Transfer(address indexed from, address indexed to, uint256 value); 13 | event Approval(address indexed owner, address indexed spender, uint256 value); 14 | 15 | function permit( 16 | address owner, 17 | address spender, 18 | uint256 value, 19 | uint256 deadline, 20 | uint8 v, 21 | bytes32 r, 22 | bytes32 s 23 | ) external; 24 | } -------------------------------------------------------------------------------- /contracts/interfaces/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IERC20 { 4 | function totalSupply() external view returns (uint256); 5 | function balanceOf(address account) external view returns (uint256); 6 | function allowance(address owner, address spender) external view returns (uint256); 7 | function approve(address spender, uint256 amount) external returns (bool); 8 | function name() external view returns (string memory); 9 | function symbol() external view returns (string memory); 10 | function decimals() external view returns (uint8); 11 | 12 | event Transfer(address indexed from, address indexed to, uint256 value); 13 | event Approval(address indexed owner, address indexed spender, uint256 value); 14 | 15 | function permit( 16 | address owner, 17 | address spender, 18 | uint256 value, 19 | uint256 deadline, 20 | uint8 v, 21 | bytes32 r, 22 | bytes32 s 23 | ) external; 24 | } -------------------------------------------------------------------------------- /interfaces/ISushiToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | 4 | interface ISushiToken { 5 | function mint(address owner, uint256 amount) external; 6 | function name() external view returns (string memory); 7 | function symbol() external view returns (string memory); 8 | function decimals() external view returns (uint8); 9 | function totalSupply() external view returns (uint256); 10 | function balanceOf(address owner) external view returns (uint256); 11 | function transfer(address to, uint256 amount) external returns (bool); 12 | function transferFrom(address from, address to, uint256 amount) external returns (bool); 13 | function approve(address spender, uint256 amount) external returns (bool); 14 | function allowance(address owner, address spender) external view returns (uint256); 15 | 16 | event Transfer(address indexed from, address indexed to, uint256 amount); 17 | event Approval(address indexed owner, address indexed spender, uint256 amount); 18 | } -------------------------------------------------------------------------------- /interfaces/IMisoAuction.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoAuction { 4 | 5 | 6 | function initAuction( 7 | address _funder, 8 | address _token, 9 | uint256 _tokenSupply, 10 | uint256 _startDate, 11 | uint256 _endDate, 12 | address _paymentCurrency, 13 | uint256 _startPrice, 14 | uint256 _minimumPrice, 15 | address _operator, 16 | address _pointList, 17 | address payable _wallet 18 | ) external; 19 | function auctionSuccessful() external view returns (bool); 20 | function finalized() external view returns (bool); 21 | function wallet() external view returns (address); 22 | function paymentCurrency() external view returns (address); 23 | function auctionToken() external view returns (address); 24 | 25 | function finalize() external; 26 | function tokenPrice() external view returns (uint256); 27 | function getTotalTokens() external view returns (uint256); 28 | } 29 | -------------------------------------------------------------------------------- /contracts/interfaces/ISushiToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | 4 | interface ISushiToken { 5 | function mint(address owner, uint256 amount) external; 6 | function name() external view returns (string memory); 7 | function symbol() external view returns (string memory); 8 | function decimals() external view returns (uint8); 9 | function totalSupply() external view returns (uint256); 10 | function balanceOf(address owner) external view returns (uint256); 11 | function transfer(address to, uint256 amount) external returns (bool); 12 | function transferFrom(address from, address to, uint256 amount) external returns (bool); 13 | function approve(address spender, uint256 amount) external returns (bool); 14 | function allowance(address owner, address spender) external view returns (uint256); 15 | 16 | event Transfer(address indexed from, address indexed to, uint256 amount); 17 | event Approval(address indexed owner, address indexed spender, uint256 amount); 18 | } -------------------------------------------------------------------------------- /contracts/interfaces/IMisoAuction.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IMisoAuction { 4 | 5 | 6 | function initAuction( 7 | address _funder, 8 | address _token, 9 | uint256 _tokenSupply, 10 | uint256 _startDate, 11 | uint256 _endDate, 12 | address _paymentCurrency, 13 | uint256 _startPrice, 14 | uint256 _minimumPrice, 15 | address _operator, 16 | address _pointList, 17 | address payable _wallet 18 | ) external; 19 | function auctionSuccessful() external view returns (bool); 20 | function finalized() external view returns (bool); 21 | function wallet() external view returns (address); 22 | function paymentCurrency() external view returns (address); 23 | function auctionToken() external view returns (address); 24 | 25 | function finalize() external; 26 | function tokenPrice() external view returns (uint256); 27 | function getTotalTokens() external view returns (uint256); 28 | } 29 | -------------------------------------------------------------------------------- /scripts/deploy_AddTokenTemplate.py: -------------------------------------------------------------------------------- 1 | from brownie import * 2 | from .settings import * 3 | from .contracts import * 4 | from .contract_addresses import * 5 | import time 6 | 7 | 8 | def main(): 9 | load_accounts() 10 | 11 | # Initialise Project 12 | operator = accounts[0] 13 | wallet = accounts[1] 14 | 15 | # GP: Split into public and miso access control 16 | access_control = deploy_access_control(operator) 17 | 18 | # Setup MISOTokenFactory 19 | miso_token_factory = deploy_miso_token_factory(access_control) 20 | mintable_token_template = deploy_mintable_token_template() 21 | fixed_token_template = deploy_fixed_token_template() 22 | sushi_token_template = deploy_sushi_token_template() 23 | 24 | # miso_token_factory.addTokenTemplate(mintable_token_template, {'from': operator} ) 25 | miso_token_factory.addTokenTemplate( 26 | fixed_token_template, {'from': operator}) 27 | miso_token_factory.addTokenTemplate( 28 | sushi_token_template, {'from': operator}) 29 | -------------------------------------------------------------------------------- /contracts/OpenZeppelin/utils/Context.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | /* 6 | * @dev Provides information about the current execution context, including the 7 | * sender of the transaction and its data. While these are generally available 8 | * via msg.sender and msg.data, they should not be accessed in such a direct 9 | * manner, since when dealing with GSN meta-transactions the account sending and 10 | * paying for execution may not be the actual sender (as far as an application 11 | * is concerned). 12 | * 13 | * This contract is only required for intermediate, library-like contracts. 14 | */ 15 | abstract contract Context { 16 | function _msgSender() internal view virtual returns (address payable) { 17 | return msg.sender; 18 | } 19 | 20 | function _msgData() internal view virtual returns (bytes memory) { 21 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 22 | return msg.data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/interfaces/IMasterChef.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | pragma experimental ABIEncoderV2; 3 | import "../Utils/BoringERC20.sol"; 4 | 5 | interface IMasterChef { 6 | using BoringERC20 for IERC20; 7 | struct UserInfo { 8 | uint256 amount; // How many LP tokens the user has provided. 9 | uint256 rewardDebt; // Reward debt. See explanation below. 10 | } 11 | 12 | struct PoolInfo { 13 | IERC20 lpToken; // Address of LP token contract. 14 | uint256 allocPoint; // How many allocation points assigned to this pool. SUSHIs to distribute per block. 15 | uint256 lastRewardBlock; // Last block number that SUSHIs distribution occurs. 16 | uint256 accSushiPerShare; // Accumulated SUSHIs per share, times 1e12. See below. 17 | } 18 | 19 | function poolInfo(uint256 pid) external view returns (IMasterChef.PoolInfo memory); 20 | function totalAllocPoint() external view returns (uint256); 21 | function deposit(uint256 _pid, uint256 _amount) external; 22 | } -------------------------------------------------------------------------------- /interfaces/IMasterChef.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | pragma experimental ABIEncoderV2; 3 | import "../contracts/Utils/BoringERC20.sol"; 4 | 5 | interface IMasterChef { 6 | using BoringERC20 for IERC20; 7 | struct UserInfo { 8 | uint256 amount; // How many LP tokens the user has provided. 9 | uint256 rewardDebt; // Reward debt. See explanation below. 10 | } 11 | 12 | struct PoolInfo { 13 | IERC20 lpToken; // Address of LP token contract. 14 | uint256 allocPoint; // How many allocation points assigned to this pool. SUSHIs to distribute per block. 15 | uint256 lastRewardBlock; // Last block number that SUSHIs distribution occurs. 16 | uint256 accSushiPerShare; // Accumulated SUSHIs per share, times 1e12. See below. 17 | } 18 | 19 | function poolInfo(uint256 pid) external view returns (IMasterChef.PoolInfo memory); 20 | function totalAllocPoint() external view returns (uint256); 21 | function deposit(uint256 _pid, uint256 _amount) external; 22 | } -------------------------------------------------------------------------------- /contracts/OpenZeppelin/utils/Strings.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | /** 6 | * @dev String operations. 7 | */ 8 | library Strings { 9 | /** 10 | * @dev Converts a `uint256` to its ASCII `string` representation. 11 | */ 12 | function toString(uint256 value) internal pure returns (string memory) { 13 | // Inspired by OraclizeAPI's implementation - MIT licence 14 | // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 15 | 16 | if (value == 0) { 17 | return "0"; 18 | } 19 | uint256 temp = value; 20 | uint256 digits; 21 | while (temp != 0) { 22 | digits++; 23 | temp /= 10; 24 | } 25 | bytes memory buffer = new bytes(digits); 26 | uint256 index = digits - 1; 27 | temp = value; 28 | while (temp != 0) { 29 | buffer[index--] = bytes1(uint8(48 + temp % 10)); 30 | temp /= 10; 31 | } 32 | return string(buffer); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/test_mintable_token.py: -------------------------------------------------------------------------------- 1 | from brownie import accounts, web3, Wei, reverts, chain 2 | from brownie.network.transaction import TransactionReceipt 3 | from brownie.convert import to_address 4 | import pytest 5 | from brownie import Contract 6 | 7 | # Fixed token 8 | 9 | # reset the chain after every test case 10 | @pytest.fixture(autouse=True) 11 | def isolation(fn_isolation): 12 | pass 13 | 14 | # def test_init(mintable_token): 15 | # name = "Mintable Token" 16 | # symbol = "MNT" 17 | # owner = accounts[0] 18 | 19 | # mintable_token.initToken(name, symbol, owner,0, {'from': owner}) 20 | # assert mintable_token.name() == name 21 | # assert mintable_token.symbol() == symbol 22 | # assert mintable_token.owner() == owner 23 | 24 | # def test_mint_token(mintable_token): 25 | # amount = 1000 * 10 ** 18 26 | # assert mintable_token.balanceOf(accounts[0]) == 0 27 | # owner = mintable_token.owner() 28 | # print(owner) 29 | # mintable_token.mint(accounts[0], amount, {'from': accounts[0]}) 30 | # assert mintable_token.balanceOf(accounts[0]) == amount -------------------------------------------------------------------------------- /scripts/deploy_auction.py: -------------------------------------------------------------------------------- 1 | from brownie import * 2 | from .settings import * 3 | from .contracts import * 4 | from .contract_addresses import * 5 | import time 6 | 7 | 8 | def main(): 9 | 10 | miso_token_factory = deploy_miso_token_factory() 11 | mintable_token_template = deploy_mintable_token_template() 12 | mintable_token = deploy_mintable_token( 13 | miso_token_factory, mintable_token_template) 14 | 15 | token_factory = deploy_token_factory() 16 | fixed_token = deploy_fixed_token(token_factory) 17 | 18 | dutch_auction_template = deploy_dutch_auction_template() 19 | auction_house = deploy_auction_house(dutch_auction_template) 20 | fixed_token.approve(auction_house, AUCTION_TOKENS, {"from": accounts[0]}) 21 | 22 | wallet = accounts[1] 23 | dutch_auction = deploy_dutch_auction( 24 | auction_house, 25 | dutch_auction_template, 26 | fixed_token, 27 | AUCTION_TOKENS, 28 | AUCTION_START, 29 | AUCTION_END, 30 | ETH_ADDRESS, 31 | AUCTION_START_PRICE, 32 | AUCTION_RESERVE, 33 | wallet 34 | ) 35 | -------------------------------------------------------------------------------- /contracts/UniswapV2/interfaces/IUniswapV2ERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IUniswapV2ERC20 { 4 | event Approval(address indexed owner, address indexed spender, uint value); 5 | event Transfer(address indexed from, address indexed to, uint value); 6 | 7 | function name() external pure returns (string memory); 8 | function symbol() external pure returns (string memory); 9 | function decimals() external pure returns (uint8); 10 | function totalSupply() external view returns (uint); 11 | function balanceOf(address owner) external view returns (uint); 12 | function allowance(address owner, address spender) external view returns (uint); 13 | 14 | function approve(address spender, uint value) external returns (bool); 15 | function transfer(address to, uint value) external returns (bool); 16 | function transferFrom(address from, address to, uint value) external returns (bool); 17 | 18 | function DOMAIN_SEPARATOR() external view returns (bytes32); 19 | function PERMIT_TYPEHASH() external pure returns (bytes32); 20 | function nonces(address owner) external view returns (uint); 21 | 22 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; 23 | } -------------------------------------------------------------------------------- /tests/settings.py: -------------------------------------------------------------------------------- 1 | TENPOW18 = 10 ** 18 2 | TENPOW6 = 10 ** 6 3 | 4 | ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' 5 | ETH_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' 6 | 7 | AUCTION_TOKENS = 10000 * TENPOW18 8 | AUCTION_TIME = 50000 9 | AUCTION_START_PRICE = 100 * TENPOW18 10 | AUCTION_RESERVE = 0.001 * TENPOW18 11 | AUCTION_MINIMUM_COMMITMENT = 10 * TENPOW18 12 | 13 | CROWDSALE_TOKENS = 10000 * TENPOW18 14 | CROWDSALE_TOKENS_2 = 10 * TENPOW18 15 | 16 | CROWDSALE_TIME = 50000 17 | CROWDSALE_RATE = 0.001 * TENPOW18 18 | CROWDSALE_RATE_2 = 1 * TENPOW18 19 | 20 | CROWDSALE_GOAL = 10 * TENPOW18 21 | CROWDSALE_GOAL_2 = 5 * TENPOW18 22 | 23 | CROWDSALE_RATE_USDC = 0.0005 * TENPOW6 24 | CROWDSALE_RATE_USDC_2 = 2 * TENPOW6 25 | 26 | CROWDSALE_GOAL_USDC = 10 * TENPOW6 27 | CROWDSALE_GOAL_USDC_2 = 5 * TENPOW6 28 | 29 | SECONDS_IN_DAY = 24*60*60 30 | 31 | TOKENS_TO_MINT = 1000 * TENPOW18 32 | ETH_TO_DEPOSIT = 1 * TENPOW18 33 | 34 | POOL_LAUNCH_DEADLINE = 10 * SECONDS_IN_DAY 35 | POOL_LAUNCH_WINDOW = 3 * SECONDS_IN_DAY 36 | POOL_LAUNCH_LOCKTIME = 30 * SECONDS_IN_DAY 37 | POOL_LIQUIDITY_PERCENT = 100 38 | HYPERBOLIC_AUCTION_FACTOR = 2 39 | 40 | DOCUMENT_NAME = "MISO" 41 | DOCUMENT_DATA = "MISO: Do you comply?" 42 | 43 | 44 | USDC_TOKENS = 1000000 * TENPOW18 -------------------------------------------------------------------------------- /brownie-config.yaml: -------------------------------------------------------------------------------- 1 | # Brownie configuration file 2 | # https://eth-brownie.readthedocs.io/en/stable/config.html 3 | network: 4 | default: development # the default network that brownie connects to 5 | settings: 6 | gas_limit: "auto" 7 | gas_price: "auto" 8 | persist: true 9 | reverting_tx_gas_limit: false # if false, reverting tx's will raise without broadcasting 10 | pytest: 11 | # these settings replace the defaults when running pytest 12 | gas_limit: 16721975 13 | default_contract_owner: true 14 | reverting_tx_gas_limit: 16721975 15 | revert_traceback: true 16 | compiler: 17 | evm_version: null 18 | minify_source: false 19 | solc: 20 | version: 0.6.12 21 | optimize: true 22 | runs: 200 23 | remappings: 24 | - "@openzeppelin=OpenZeppelin/openzeppelin-contracts@3.2.0" 25 | dependencies: 26 | - OpenZeppelin/openzeppelin-contracts@3.2.0 27 | colors: 28 | key: 29 | value: bright blue 30 | callable: bright cyan 31 | module: bright blue 32 | contract: bright magenta 33 | contract_method: bright magenta 34 | string: bright magenta 35 | dull: dark white 36 | error: bright red 37 | success: bright green 38 | pending: bright yellow 39 | -------------------------------------------------------------------------------- /contracts/Tokens/ERC20/ERC20Burnable.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity ^0.6.0; 4 | 5 | import "../ERC20.sol"; 6 | 7 | /** 8 | * @dev Extension of {ERC20} that allows token holders to destroy both their own 9 | * tokens and those that they have an allowance for, in a way that can be 10 | * recognized off-chain (via event analysis). 11 | */ 12 | abstract contract ERC20Burnable is ERC20 { 13 | /** 14 | * @dev Destroys `amount` tokens from the caller. 15 | * 16 | * See {ERC20-_burn}. 17 | */ 18 | function burn(uint256 amount) public virtual { 19 | _burn(_msgSender(), amount); 20 | } 21 | 22 | /** 23 | * @dev Destroys `amount` tokens from `account`, deducting from the callers 24 | * allowance. 25 | * 26 | * See {ERC20-_burn} and {ERC20-allowance}. 27 | * 28 | * Requirements: 29 | * 30 | * - the caller must have allowance for ``accounts``s tokens of at least 31 | * `amount`. 32 | */ 33 | function burnFrom(address account, uint256 amount) public virtual { 34 | uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance"); 35 | 36 | _approve(account, _msgSender(), decreasedAllowance); 37 | _burn(account, amount); 38 | } 39 | } -------------------------------------------------------------------------------- /contracts/Utils/Owned.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | 4 | // import "../../interfaces/IERC20.sol"; 5 | 6 | 7 | contract Owned { 8 | 9 | address private mOwner; 10 | bool private initialised; 11 | address public newOwner; 12 | 13 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 14 | 15 | modifier onlyOwner() { 16 | require(isOwner()); 17 | _; 18 | } 19 | 20 | function _initOwned(address _owner) internal { 21 | require(!initialised); 22 | mOwner = address(uint160(_owner)); 23 | initialised = true; 24 | emit OwnershipTransferred(address(0), mOwner); 25 | } 26 | 27 | function owner() public view returns (address) { 28 | return mOwner; 29 | } 30 | function isOwner() public view returns (bool) { 31 | return msg.sender == mOwner; 32 | } 33 | 34 | function transferOwnership(address _newOwner) public { 35 | require(isOwner()); 36 | newOwner = _newOwner; 37 | } 38 | 39 | function acceptOwnership() public { 40 | require(msg.sender == newOwner); 41 | emit OwnershipTransferred(mOwner, newOwner); 42 | mOwner = address(uint160(newOwner)); 43 | newOwner = address(0); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /scripts/verify.py: -------------------------------------------------------------------------------- 1 | from brownie import * 2 | from .settings import * 3 | from .contracts import * 4 | from .contract_addresses import * 5 | import time 6 | 7 | 8 | def verify(contract_id, container): 9 | contract_address = CONTRACTS[network.show_active()][contract_id] 10 | contract = container.at(contract_address) 11 | print(contract_id, ": Verification initiated..") 12 | try: 13 | container.publish_source(contract) 14 | # print(container.get_verification_info()) 15 | except: 16 | print(contract_id, ": Already verified") 17 | 18 | 19 | def main(): 20 | 21 | # verify("miso_token_factory", MISOTokenFactory) 22 | # verify("miso_launcher", MISOLauncher) 23 | # verify("mintable_token_template", MintableToken) 24 | # verify("fixed_token_template", FixedToken) 25 | # verify("sushi_token_template", SushiToken) 26 | # verify("dutch_auction_template", DutchAuction) 27 | verify("crowdsale_template", Crowdsale) 28 | # verify("pool_liquidity_template", PoolLiquidity) 29 | # verify("post_auction_launcher_template", PoolLiquidity) 30 | 31 | # verify("miso_market", MISOMarket) 32 | # verify("weth_token", WETH9) 33 | # verify("access_control", MISOAccessControls) 34 | # verify("masterchef_template", MISOMasterChef) 35 | # verify("farm_factory", MISOFarmFactory) 36 | # verify("miso_helper", MISOHelper) 37 | -------------------------------------------------------------------------------- /tests/test_auction_factory.py: -------------------------------------------------------------------------------- 1 | # import pytest 2 | # from brownie import accounts, chain 3 | # from brownie.convert import to_address 4 | # from settings import * 5 | 6 | # # reset the chain after every test case 7 | # @pytest.fixture(autouse=True) 8 | # def isolation(fn_isolation): 9 | # pass 10 | 11 | # def test_create_auction(auction_factory, fixed_token, mintable_token): 12 | # token_supply = fixed_token.balanceOf(accounts[0]) 13 | 14 | # assert token_supply != 0 15 | 16 | # fixed_token.approve(auction_factory, token_supply, {"from": accounts[0]}) 17 | 18 | # start_date = chain.time() + 60 * 5 # current time + 5 minutes 19 | # end_date = start_date + 60 * 60 # start date + 60 minutes 20 | # start_price = 50000000000000000 21 | # minimum_price = 10000000000000000 22 | # wallet = accounts[0] 23 | 24 | # print("start_date", start_date) 25 | # print("end_date", end_date) 26 | 27 | # template_id = auction_factory.getTemplateId(fixed_token) 28 | 29 | # print("template_id:", template_id) 30 | 31 | # auction_factory.createAuction( 32 | # fixed_token, 33 | # token_supply, 34 | # start_date, 35 | # end_date, 36 | # ETH_ADDRESS, 37 | # start_price, 38 | # minimum_price, 39 | # wallet, 40 | # template_id, 41 | # {"from": accounts[0]} 42 | # ) 43 | -------------------------------------------------------------------------------- /spec/scripts/applyHarness.sh: -------------------------------------------------------------------------------- 1 | # change import "../Utils/SafeTransfer.sol" to harness code in spec/harness/SafeTransfer.sol 2 | perl -0777 -i -pe 's/\.\.\/Utils\/SafeTransfer\.sol/\.\.\/\.\.\/spec\/harness\/SafeTransfer.sol/g' contracts/Auctions/DutchAuction.sol 3 | 4 | # change import "../Access/MISOAccessControls.sol" to harness code in spec/harness/MISOAccessControls.sol 5 | perl -0777 -i -pe 's/\.\.\/Access\/MISOAccessControls\.sol/\.\.\/\.\.\/spec\/harness\/MISOAccessControls.sol/g' contracts/Auctions/DutchAuction.sol 6 | 7 | # change import ""../Utils/Documents.sol" to harnness code in spec/harness/Document.sol 8 | perl -0777 -i -pe 's/\.\.\/Utils\/Documents\.sol/\.\.\/\.\.\/spec\/harness\/Documents.sol/g' contracts/Auctions/DutchAuction.sol 9 | 10 | # virtualize private function 11 | perl -0777 -i -pe 's/\) private view /\) internal virtual view /g' contracts/Auctions/DutchAuction.sol 12 | 13 | # change eth transfer 14 | perl -0777 -i -pe 's/_beneficiary.transfer\(/_safeTokenPayment\(paymentCurrency,_beneficiary,/g' contracts/Auctions/DutchAuction.sol 15 | # virtualize public function 16 | perl -0777 -i -pe 's/public view returns/public virtual view returns/g' contracts/Auctions/DutchAuction.sol 17 | 18 | # virtualize batch 19 | perl -0777 -i -pe 's/function batch\(bytes\[\] calldata calls, bool revertOnFail\) external/function batch\(bytes\[\] calldata calls, bool revertOnFail\) external virtual/g' contracts/Utils/BoringBatchable.sol -------------------------------------------------------------------------------- /contracts/UniswapV2/interfaces/IUniswapV2Router02.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import './IUniswapV2Router01.sol'; 4 | 5 | interface IUniswapV2Router02 is IUniswapV2Router01 { 6 | function removeLiquidityETHSupportingFeeOnTransferTokens( 7 | address token, 8 | uint liquidity, 9 | uint amountTokenMin, 10 | uint amountETHMin, 11 | address to, 12 | uint deadline 13 | ) external returns (uint amountETH); 14 | function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( 15 | address token, 16 | uint liquidity, 17 | uint amountTokenMin, 18 | uint amountETHMin, 19 | address to, 20 | uint deadline, 21 | bool approveMax, uint8 v, bytes32 r, bytes32 s 22 | ) external returns (uint amountETH); 23 | 24 | function swapExactTokensForTokensSupportingFeeOnTransferTokens( 25 | uint amountIn, 26 | uint amountOutMin, 27 | address[] calldata path, 28 | address to, 29 | uint deadline 30 | ) external; 31 | function swapExactETHForTokensSupportingFeeOnTransferTokens( 32 | uint amountOutMin, 33 | address[] calldata path, 34 | address to, 35 | uint deadline 36 | ) external payable; 37 | function swapExactTokensForETHSupportingFeeOnTransferTokens( 38 | uint amountIn, 39 | uint amountOutMin, 40 | address[] calldata path, 41 | address to, 42 | uint deadline 43 | ) external; 44 | } -------------------------------------------------------------------------------- /contracts/UniswapV2/libraries/TransferHelper.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity 0.6.12; 3 | 4 | // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false 5 | library TransferHelper { 6 | function safeApprove(address token, address to, uint value) internal { 7 | // bytes4(keccak256(bytes('approve(address,uint256)'))); 8 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); 9 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); 10 | } 11 | 12 | function safeTransfer(address token, address to, uint value) internal { 13 | // bytes4(keccak256(bytes('transfer(address,uint256)'))); 14 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); 15 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); 16 | } 17 | 18 | function safeTransferFrom(address token, address from, address to, uint value) internal { 19 | // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); 20 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); 21 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); 22 | } 23 | 24 | function safeTransferETH(address to, uint value) internal { 25 | (bool success,) = to.call{value:value}(new bytes(0)); 26 | require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/Access/TokenList.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "../interfaces/IPointList.sol"; 4 | import "../interfaces/IERC20.sol"; 5 | 6 | /** 7 | * @notice TokenPointList - MISO Point List that references a given `token` balance to return approvals. 8 | */ 9 | contract TokenList { 10 | /// @notice Token contract for point list reference - can be ERC20, ERC721 or other tokens with `balanceOf()` check. 11 | IERC20 public token; 12 | 13 | /// @notice Whether initialised or not. 14 | bool private initialised; 15 | 16 | constructor() public { 17 | } 18 | 19 | /** 20 | * @notice Initializes token point list with reference token. 21 | * @param _token Token address. 22 | */ 23 | function initPointList(IERC20 _token) public { 24 | require(!initialised, "Already initialised"); 25 | token = _token; 26 | initialised = true; 27 | } 28 | 29 | /** 30 | * @notice Checks if account address is in the list (has any tokens). 31 | * @param _account Account address. 32 | * @return bool True or False. 33 | */ 34 | function isInList(address _account) public view returns (bool) { 35 | return token.balanceOf(_account) > 0; 36 | } 37 | 38 | /** 39 | * @notice Checks if account has more or equal points (tokens) as the number given. 40 | * @param _account Account address. 41 | * @param _amount Desired amount of points. 42 | * @return bool True or False. 43 | */ 44 | function hasPoints(address _account, uint256 _amount) public view returns (bool) { 45 | return token.balanceOf(_account) >= _amount; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/OpenZeppelin/utils/Arrays.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "../math/Math.sol"; 6 | 7 | /** 8 | * @dev Collection of functions related to array types. 9 | */ 10 | library Arrays { 11 | /** 12 | * @dev Searches a sorted `array` and returns the first index that contains 13 | * a value greater or equal to `element`. If no such index exists (i.e. all 14 | * values in the array are strictly less than `element`), the array length is 15 | * returned. Time complexity O(log n). 16 | * 17 | * `array` is expected to be sorted in ascending order, and to contain no 18 | * repeated elements. 19 | */ 20 | function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { 21 | if (array.length == 0) { 22 | return 0; 23 | } 24 | 25 | uint256 low = 0; 26 | uint256 high = array.length; 27 | 28 | while (low < high) { 29 | uint256 mid = Math.average(low, high); 30 | 31 | // Note that mid will always be strictly less than high (i.e. it will be a valid array index) 32 | // because Math.average rounds down (it does integer division with truncation). 33 | if (array[mid] > element) { 34 | high = mid; 35 | } else { 36 | low = mid + 1; 37 | } 38 | } 39 | 40 | // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. 41 | if (low > 0 && array[low - 1] == element) { 42 | return low - 1; 43 | } else { 44 | return low; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/OpenZeppelin/utils/Counters.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "../math/SafeMath.sol"; 6 | 7 | /** 8 | * @title Counters 9 | * @author Matt Condon (@shrugs) 10 | * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number 11 | * of elements in a mapping, issuing ERC721 ids, or counting request ids. 12 | * 13 | * Include with `using Counters for Counters.Counter;` 14 | * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} 15 | * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never 16 | * directly accessed. 17 | */ 18 | library Counters { 19 | using SafeMath for uint256; 20 | 21 | struct Counter { 22 | // This variable should never be directly accessed by users of the library: interactions must be restricted to 23 | // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add 24 | // this feature: see https://github.com/ethereum/solidity/issues/4637 25 | uint256 _value; // default: 0 26 | } 27 | 28 | function current(Counter storage counter) internal view returns (uint256) { 29 | return counter._value; 30 | } 31 | 32 | function increment(Counter storage counter) internal { 33 | // The {SafeMath} overflow check can be skipped here, see the comment at the top 34 | counter._value += 1; 35 | } 36 | 37 | function decrement(Counter storage counter) internal { 38 | counter._value = counter._value.sub(1); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .history 3 | .hypothesis/ 4 | build/ 5 | reports/ 6 | .vscode 7 | 8 | # Created by .ignore support plugin (hsz.mobi) 9 | ### Node template 10 | # Logs 11 | logs 12 | *.log 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional REPL history 58 | .node_repl_history 59 | 60 | # Output of 'npm pack' 61 | *.tgz 62 | 63 | # Yarn Integrity file 64 | .yarn-integrity 65 | 66 | # dotenv environment variables file 67 | .env 68 | .env* 69 | 70 | # parcel-bundler cache (https://parceljs.org/) 71 | .cache 72 | 73 | # next.js build output 74 | .next 75 | 76 | # nuxt.js build output 77 | .nuxt 78 | 79 | # Nuxt generate 80 | dist 81 | 82 | # vuepress build output 83 | .vuepress/dist 84 | 85 | # Serverless directories 86 | .serverless 87 | 88 | # IDE 89 | .idea 90 | .vscode 91 | 92 | # Service worker 93 | sw.* 94 | 95 | yarn.lock 96 | 97 | package-lock.json 98 | -------------------------------------------------------------------------------- /tests/test_access_control.py: -------------------------------------------------------------------------------- 1 | from brownie import accounts, web3, Wei, reverts, chain 2 | from brownie.network.transaction import TransactionReceipt 3 | from brownie.convert import to_address 4 | import pytest 5 | from brownie import Contract 6 | from settings import * 7 | 8 | def test_smart_contract_role(miso_access_controls): 9 | miso_access_controls.addSmartContractRole(accounts[1],{"from":accounts[0]}) 10 | assert(miso_access_controls.hasSmartContractRole(accounts[1])) 11 | 12 | miso_access_controls.removeSmartContractRole(accounts[1],{"from":accounts[0]}) 13 | assert(miso_access_controls.hasSmartContractRole(accounts[1])==False) 14 | 15 | def test_minter_role(miso_access_controls): 16 | miso_access_controls.addMinterRole(accounts[1],{"from":accounts[0]}) 17 | assert(miso_access_controls.hasMinterRole(accounts[1])) 18 | 19 | miso_access_controls.removeMinterRole(accounts[1],{"from":accounts[0]}) 20 | assert(miso_access_controls.hasMinterRole(accounts[1])==False) 21 | 22 | def test_operator_role(miso_access_controls): 23 | miso_access_controls.addOperatorRole(accounts[1],{"from":accounts[0]}) 24 | assert(miso_access_controls.hasOperatorRole(accounts[1])) 25 | 26 | miso_access_controls.removeOperatorRole(accounts[1],{"from":accounts[0]}) 27 | assert(miso_access_controls.hasOperatorRole(accounts[1])==False) 28 | 29 | def test_admin_role(miso_access_controls): 30 | miso_access_controls.addAdminRole(accounts[1],{"from":accounts[0]}) 31 | assert(miso_access_controls.hasAdminRole(accounts[1])) 32 | 33 | miso_access_controls.removeAdminRole(accounts[1],{"from":accounts[0]}) 34 | assert(miso_access_controls.hasAdminRole(accounts[1])==False) 35 | 36 | def test_init_again(miso_access_controls): 37 | with reverts("Already initialised"): 38 | miso_access_controls.initAccessControls(accounts[0], {"from":accounts[0]}) -------------------------------------------------------------------------------- /spec/harness/Documents.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | pragma experimental ABIEncoderV2; 3 | 4 | /** 5 | * @title Simplified version of the Document.sol for verification with 6 | * Certora Prover. 7 | */ 8 | contract Documents { 9 | function _setDocument(string calldata _name, string calldata _data) internal { } 10 | 11 | /** 12 | * @notice Used to remove an existing document from the contract by giving the name of the document. 13 | * @dev Can only be executed by the owner of the contract. 14 | * @param _name Name of the document. It should be unique always 15 | */ 16 | function _removeDocument(string calldata _name) internal { } 17 | 18 | /** 19 | * @notice Used to return the details of a document with a known name (`string`). 20 | * @param _name Name of the document 21 | * @return string The data associated with the document. 22 | * @return uint256 the timestamp at which the document was last modified. 23 | */ 24 | function getDocument(string calldata _name) external view returns (string memory, uint256) { } 25 | 26 | /** 27 | * @notice Used to retrieve a full list of documents attached to the smart contract. 28 | * @return string List of all documents names present in the contract. 29 | */ 30 | function getAllDocuments() external view returns (string[] memory) { } 31 | 32 | /** 33 | * @notice Used to retrieve the total documents in the smart contract. 34 | * @return uint256 Count of the document names present in the contract. 35 | */ 36 | function getDocumentCount() external view returns (uint256) { } 37 | 38 | /** 39 | * @notice Used to retrieve the document name from index in the smart contract. 40 | * @return string Name of the document name. 41 | */ 42 | function getDocumentName(uint256 _index) external view returns (string memory) { } 43 | } 44 | -------------------------------------------------------------------------------- /spec/harness/DummyERC20A.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity ^0.6.8; 3 | 4 | /** 5 | * Dummy ERC20 token. 6 | */ 7 | contract DummyERC20A { 8 | uint256 t; 9 | 10 | mapping(address => uint256) b; 11 | mapping(address => mapping(address => uint256)) a; 12 | 13 | string public name; 14 | string public symbol; 15 | uint public decimals; 16 | 17 | function myAddress() public returns (address) { 18 | return address(this); 19 | } 20 | 21 | function add(uint a, uint b) internal pure returns (uint256) { 22 | uint c = a + b; 23 | require (c >= a); 24 | return c; 25 | } 26 | 27 | function sub(uint a, uint b) internal pure returns (uint256) { 28 | require (a >= b); 29 | return a - b; 30 | } 31 | 32 | function totalSupply() external view returns (uint256) { 33 | return t; 34 | } 35 | 36 | function balanceOf(address account) external view returns (uint256) { 37 | return b[account]; 38 | } 39 | 40 | function transfer(address recipient, uint256 amount) external returns (bool) { 41 | b[msg.sender] = sub(b[msg.sender], amount); 42 | b[recipient] = add(b[recipient], amount); 43 | return true; 44 | } 45 | 46 | function allowance(address owner, address spender) external view returns (uint256) { 47 | return a[owner][spender]; 48 | } 49 | 50 | function approve(address spender, uint256 amount) external returns (bool) { 51 | a[msg.sender][spender] = amount; 52 | return true; 53 | } 54 | 55 | function transferFrom( 56 | address sender, 57 | address recipient, 58 | uint256 amount 59 | ) external returns (bool) { 60 | b[sender] = sub(b[sender], amount); 61 | b[recipient] = add(b[recipient], amount); 62 | a[sender][msg.sender] = sub(a[sender][msg.sender], amount); 63 | return true; 64 | } 65 | } -------------------------------------------------------------------------------- /spec/harness/DummyERC20B.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity ^0.6.8; 3 | 4 | /** 5 | * Dummy ERC20 token. 6 | */ 7 | contract DummyERC20B { 8 | uint256 t; 9 | 10 | mapping(address => uint256) b; 11 | mapping(address => mapping(address => uint256)) a; 12 | 13 | string public name; 14 | string public symbol; 15 | uint public decimals; 16 | 17 | function myAddress() public returns (address) { 18 | return address(this); 19 | } 20 | 21 | function add(uint a, uint b) internal pure returns (uint256) { 22 | uint c = a + b; 23 | require (c >= a); 24 | return c; 25 | } 26 | 27 | function sub(uint a, uint b) internal pure returns (uint256) { 28 | require (a >= b); 29 | return a - b; 30 | } 31 | 32 | function totalSupply() external view returns (uint256) { 33 | return t; 34 | } 35 | 36 | function balanceOf(address account) external view returns (uint256) { 37 | return b[account]; 38 | } 39 | 40 | function transfer(address recipient, uint256 amount) external returns (bool) { 41 | b[msg.sender] = sub(b[msg.sender], amount); 42 | b[recipient] = add(b[recipient], amount); 43 | return true; 44 | } 45 | 46 | function allowance(address owner, address spender) external view returns (uint256) { 47 | return a[owner][spender]; 48 | } 49 | 50 | function approve(address spender, uint256 amount) external returns (bool) { 51 | a[msg.sender][spender] = amount; 52 | return true; 53 | } 54 | 55 | function transferFrom( 56 | address sender, 57 | address recipient, 58 | uint256 amount 59 | ) external returns (bool) { 60 | b[sender] = sub(b[sender], amount); 61 | b[recipient] = add(b[recipient], amount); 62 | a[sender][msg.sender] = sub(a[sender][msg.sender], amount); 63 | return true; 64 | } 65 | } -------------------------------------------------------------------------------- /spec/harness/SafeTransfer.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | /** 4 | * Simplified version for easy of verification using Certora Prover. 5 | */ 6 | interface ISimpleERC20 { 7 | function approve(address spender, uint256 amount) external returns (bool); 8 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 9 | function transfer(address recipient, uint256 amount) external returns (bool); 10 | } 11 | 12 | interface Receiver { 13 | function sendTo() external payable returns (bool); 14 | } 15 | 16 | contract SafeTransfer { 17 | address private constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; 18 | 19 | function _safeTokenPayment( 20 | address _token, 21 | address payable _to, 22 | uint256 _amount 23 | ) internal { 24 | if (address(_token) == ETH_ADDRESS) { 25 | _safeTransferETH(_to,_amount ); 26 | } else { 27 | _safeTransfer(_token, _to, _amount); 28 | } 29 | } 30 | 31 | function _safeApprove(address token, address to, uint value) internal { 32 | ISimpleERC20(token).approve(to, value); 33 | } 34 | 35 | function _safeTransfer( 36 | address token, 37 | address to, 38 | uint256 amount 39 | ) internal virtual { 40 | ISimpleERC20(token).transfer(to, amount); 41 | } 42 | 43 | function _safeTransferFrom( 44 | address token, 45 | address from, 46 | uint256 amount 47 | ) internal virtual { 48 | ISimpleERC20(token).transferFrom(from, address(this), amount); 49 | } 50 | 51 | function _safeTransferFrom(address token, address from, address to, uint value) internal { 52 | ISimpleERC20(token).transferFrom(from, to, value); 53 | } 54 | 55 | function _safeTransferETH(address to, uint value) internal { 56 | bool success = Receiver(to).sendTo{value:value}(); 57 | require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); 58 | } 59 | } -------------------------------------------------------------------------------- /scripts/deploy_gnosis.py: -------------------------------------------------------------------------------- 1 | from brownie import * 2 | from .settings import * 3 | from .contracts import * 4 | from .contract_addresses import * 5 | import time 6 | 7 | 8 | def deploy_gnosis_safe(): 9 | gnosis_safe_address = CONTRACTS[network.show_active()]["gnosis_safe"] 10 | if gnosis_safe_address == "": 11 | gnosis_safe_master_copy = GnosisSafe.deploy({"from": accounts[0]}) 12 | else: 13 | gnosis_safe_master_copy = GnosisSafe.at(gnosis_safe_address) 14 | 15 | return gnosis_safe_master_copy 16 | 17 | 18 | def deploy_proxy_factory(): 19 | proxy_factory_address = CONTRACTS[network.show_active()]["proxy_factory"] 20 | if proxy_factory_address == "": 21 | proxy_factory = ProxyFactory.deploy({"from": accounts[0]}) 22 | else: 23 | proxy_factory = ProxyFactory.at(proxy_factory_address) 24 | return proxy_factory 25 | 26 | 27 | def deploy_gnosis_vault(): 28 | gnosis_vault_address = CONTRACTS[network.show_active()]["gnosis_vault"] 29 | if gnosis_vault_address == "": 30 | gnosis_vault = GnosisVault.deploy({"from": accounts[0]}) 31 | else: 32 | gnosis_vault = GnosisVault.at(gnosis_vault_address) 33 | 34 | return gnosis_vault 35 | 36 | 37 | def main(): 38 | load_accounts() 39 | gnosis_safe = CONTRACTS[network.show_active()]["gnosis_safe"] 40 | proxy_factory = CONTRACTS[network.show_active()]["proxy_factory"] 41 | 42 | gnosis_vault = deploy_gnosis_vault() 43 | gnosis_vault.initGnosisVault( 44 | gnosis_safe, proxy_factory, {"from": accounts[0]}) 45 | 46 | owners = [accounts[0], accounts[1]] 47 | threshold = 1 48 | delegate_to = ZERO_ADDRESS 49 | data = "0x" 50 | handle_fallback = ZERO_ADDRESS 51 | payment_token = ZERO_ADDRESS 52 | gasPrice = 50 53 | payment = 5000 * gasPrice 54 | paymentReceiver = accounts[1] 55 | 56 | proxy = gnosis_vault.createSafe( 57 | owners, 58 | threshold, 59 | delegate_to, 60 | data, 61 | handle_fallback, 62 | payment_token, 63 | payment, 64 | paymentReceiver) 65 | -------------------------------------------------------------------------------- /spec/harness/DummyWeth.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: agpl-3.0 2 | pragma solidity ^0.6.8; 3 | 4 | /** 5 | * Dummy Weth token. 6 | */ 7 | contract DummyWeth { 8 | uint256 t; 9 | 10 | mapping(address => uint256) b; 11 | mapping(address => mapping(address => uint256)) a; 12 | 13 | string public name; 14 | string public symbol; 15 | uint public decimals; 16 | 17 | function myAddress() public returns (address) { 18 | return address(this); 19 | } 20 | 21 | function add(uint a, uint b) internal pure returns (uint256) { 22 | uint c = a + b; 23 | require (c >= a); 24 | return c; 25 | } 26 | function sub(uint a, uint b) internal pure returns (uint256) { 27 | require (a >= b); 28 | return a - b; 29 | } 30 | 31 | function totalSupply() external view returns (uint256) { 32 | return t; 33 | } 34 | 35 | function balanceOf(address account) external view returns (uint256) { 36 | return b[account]; 37 | } 38 | 39 | function transfer(address recipient, uint256 amount) external returns (bool) { 40 | b[msg.sender] = sub(b[msg.sender], amount); 41 | b[recipient] = add(b[recipient], amount); 42 | return true; 43 | } 44 | 45 | function allowance(address owner, address spender) external view returns (uint256) { 46 | return a[owner][spender]; 47 | } 48 | 49 | function approve(address spender, uint256 amount) external returns (bool) { 50 | a[msg.sender][spender] = amount; 51 | return true; 52 | } 53 | 54 | function transferFrom( 55 | address sender, 56 | address recipient, 57 | uint256 amount 58 | ) external returns (bool) { 59 | b[sender] = sub(b[sender], amount); 60 | b[recipient] = add(b[recipient], amount); 61 | a[sender][msg.sender] = sub(a[sender][msg.sender], amount); 62 | return true; 63 | } 64 | 65 | // WETH 66 | function deposit() external payable { 67 | // assume succeeds 68 | } 69 | 70 | function withdraw(uint256) external { 71 | // assume succeeds 72 | } 73 | } -------------------------------------------------------------------------------- /contracts/OpenZeppelin/token/ERC20/TokenTimelock.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "./SafeERC20.sol"; 6 | 7 | /** 8 | * @dev A token holder contract that will allow a beneficiary to extract the 9 | * tokens after a given release time. 10 | * 11 | * Useful for simple vesting schedules like "advisors get all of their tokens 12 | * after 1 year". 13 | */ 14 | contract TokenTimelock { 15 | using SafeERC20 for IERC20; 16 | 17 | // ERC20 basic token contract being held 18 | IERC20 private _token; 19 | 20 | // beneficiary of tokens after they are released 21 | address private _beneficiary; 22 | 23 | // timestamp when token release is enabled 24 | uint256 private _releaseTime; 25 | 26 | constructor (IERC20 token_, address beneficiary_, uint256 releaseTime_) public { 27 | // solhint-disable-next-line not-rely-on-time 28 | require(releaseTime_ > block.timestamp, "TokenTimelock: release time is before current time"); 29 | _token = token_; 30 | _beneficiary = beneficiary_; 31 | _releaseTime = releaseTime_; 32 | } 33 | 34 | /** 35 | * @return the token being held. 36 | */ 37 | function token() public view virtual returns (IERC20) { 38 | return _token; 39 | } 40 | 41 | /** 42 | * @return the beneficiary of the tokens. 43 | */ 44 | function beneficiary() public view virtual returns (address) { 45 | return _beneficiary; 46 | } 47 | 48 | /** 49 | * @return the time when the tokens are released. 50 | */ 51 | function releaseTime() public view virtual returns (uint256) { 52 | return _releaseTime; 53 | } 54 | 55 | /** 56 | * @notice Transfers tokens held by timelock to beneficiary. 57 | */ 58 | function release() public virtual { 59 | // solhint-disable-next-line not-rely-on-time 60 | require(block.timestamp >= releaseTime(), "TokenTimelock: current time is before release time"); 61 | 62 | uint256 amount = token().balanceOf(address(this)); 63 | require(amount > 0, "TokenTimelock: no tokens to release"); 64 | 65 | token().safeTransfer(beneficiary(), amount); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /contracts/Tokens/FixedToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "./ERC20.sol"; 4 | import "../interfaces/IMisoToken.sol"; 5 | 6 | // --------------------------------------------------------------------- 7 | // 8 | // From the MISO Token Factory 9 | // 10 | // Made for Sushi.com 11 | // 12 | // Enjoy. (c) Chef Gonpachi 2021 13 | // 14 | // 15 | // --------------------------------------------------------------------- 16 | // SPDX-License-Identifier: GPL-3.0 17 | // --------------------------------------------------------------------- 18 | 19 | contract FixedToken is ERC20, IMisoToken { 20 | 21 | /// @notice Miso template id for the token factory. 22 | /// @dev For different token types, this must be incremented. 23 | uint256 public constant override tokenTemplate = 1; 24 | 25 | /// @dev First set the token variables. This can only be done once 26 | function initToken(string memory _name, string memory _symbol, address _owner, uint256 _initialSupply) public { 27 | _initERC20(_name, _symbol); 28 | _mint(msg.sender, _initialSupply); 29 | } 30 | function init(bytes calldata _data) external override payable {} 31 | 32 | function initToken( 33 | bytes calldata _data 34 | ) public override { 35 | (string memory _name, 36 | string memory _symbol, 37 | address _owner, 38 | uint256 _initialSupply) = abi.decode(_data, (string, string, address, uint256)); 39 | 40 | initToken(_name,_symbol,_owner,_initialSupply); 41 | } 42 | 43 | /** 44 | * @dev Generates init data for Farm Factory 45 | * @param _name - Token name 46 | * @param _symbol - Token symbol 47 | * @param _owner - Contract owner 48 | * @param _initialSupply Amount of tokens minted on creation 49 | */ 50 | function getInitData( 51 | string calldata _name, 52 | string calldata _symbol, 53 | address _owner, 54 | uint256 _initialSupply 55 | ) 56 | external 57 | pure 58 | returns (bytes memory _data) 59 | { 60 | return abi.encode(_name, _symbol, _owner, _initialSupply); 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /spec/harness/DutchAuctionHarness.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import "../../contracts/Auctions/DutchAuction.sol"; 5 | 6 | /* 7 | * Harness for the DutchAuction to support the Certora Prover. 8 | * Contains some simplifications and helper getter methods. 9 | */ 10 | contract DutchAuctionHarness is DutchAuction { 11 | address private constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; 12 | 13 | mapping(uint256 => uint256) public currentPrice; 14 | mapping(uint256 => uint256 ) public tokenPrice_; 15 | 16 | //////////////////////////////////////////////////////////// 17 | // Getters // 18 | //////////////////////////////////////////////////////////// 19 | 20 | function tokenBalanceOf(address token, address user) public returns (uint256) { 21 | if (token == ETH_ADDRESS) { 22 | return address(user).balance; 23 | } else { 24 | return IERC20(token).balanceOf(user); 25 | } 26 | } 27 | 28 | function getCommitmentsTotal() public returns (uint256) { 29 | return marketStatus.commitmentsTotal; 30 | } 31 | 32 | function getStartPrice() public returns (uint256) { 33 | return marketPrice.startPrice; 34 | } 35 | 36 | //////////////////////////////////////////////////////////// 37 | // Simplifications // 38 | //////////////////////////////////////////////////////////// 39 | 40 | function _currentPrice() internal override view returns (uint256) { 41 | uint256 price = currentPrice[block.timestamp]; 42 | require(price <= marketPrice.startPrice); 43 | require(price >= marketPrice.minimumPrice); 44 | return price; 45 | } 46 | 47 | function clearingPrice() public override view returns (uint256) { 48 | uint256 tokenPrice_ = tokenPrice(); 49 | uint256 priceFunction_ = priceFunction(); 50 | if (tokenPrice_ > priceFunction_) { 51 | return tokenPrice_; 52 | } 53 | return priceFunction_; 54 | } 55 | 56 | function batch(bytes[] calldata calls, bool revertOnFail) external override payable 57 | returns (bool[] memory successes, bytes[] memory results) { } 58 | } -------------------------------------------------------------------------------- /contracts/OpenZeppelin/token/ERC20/README.adoc: -------------------------------------------------------------------------------- 1 | = ERC 20 2 | 3 | [.readme-notice] 4 | NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/token/erc20 5 | 6 | This set of interfaces, contracts, and utilities are all related to the https://eips.ethereum.org/EIPS/eip-20[ERC20 Token Standard]. 7 | 8 | TIP: For an overview of ERC20 tokens and a walk through on how to create a token contract read our xref:ROOT:erc20.adoc[ERC20 guide]. 9 | 10 | There a few core contracts that implement the behavior specified in the EIP: 11 | 12 | * {IERC20}: the interface all ERC20 implementations should conform to. 13 | * {ERC20}: the implementation of the ERC20 interface, including the <>, <> and <> optional standard extension to the base interface. 14 | 15 | Additionally there are multiple custom extensions, including: 16 | 17 | * {ERC20Permit}: gasless approval of tokens. 18 | * {ERC20Snapshot}: efficient storage of past token balances to be later queried at any point in time. 19 | * {ERC20Burnable}: destruction of own tokens. 20 | * {ERC20Capped}: enforcement of a cap to the total supply when minting tokens. 21 | * {ERC20Pausable}: ability to pause token transfers. 22 | 23 | Finally, there are some utilities to interact with ERC20 contracts in various ways. 24 | 25 | * {SafeERC20}: a wrapper around the interface that eliminates the need to handle boolean return values. 26 | * {TokenTimelock}: hold tokens for a beneficiary until a specified time. 27 | 28 | The following related EIPs are in draft status and can be found in the drafts directory. 29 | 30 | - {IERC20Permit} 31 | - {ERC20Permit} 32 | 33 | NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC20 (such as <>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc20.adoc#Presets[ERC20 Presets] (such as {ERC20PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts. 34 | 35 | == Core 36 | 37 | {{IERC20}} 38 | 39 | {{ERC20}} 40 | 41 | == Extensions 42 | 43 | {{ERC20Snapshot}} 44 | 45 | {{ERC20Pausable}} 46 | 47 | {{ERC20Burnable}} 48 | 49 | {{ERC20Capped}} 50 | 51 | == Utilities 52 | 53 | {{SafeERC20}} 54 | 55 | {{TokenTimelock}} 56 | -------------------------------------------------------------------------------- /contracts/Access/MISOAdminAccess.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "../OpenZeppelin/access/AccessControl.sol"; 4 | 5 | 6 | contract MISOAdminAccess is AccessControl { 7 | 8 | /// @dev Whether access is initialised. 9 | bool private initAccess; 10 | 11 | /// @notice Events for adding and removing various roles. 12 | event AdminRoleGranted( 13 | address indexed beneficiary, 14 | address indexed caller 15 | ); 16 | 17 | event AdminRoleRemoved( 18 | address indexed beneficiary, 19 | address indexed caller 20 | ); 21 | 22 | 23 | /// @notice The deployer is automatically given the admin role which will allow them to then grant roles to other addresses. 24 | constructor() public { 25 | } 26 | 27 | /** 28 | * @notice Initializes access controls. 29 | * @param _admin Admins address. 30 | */ 31 | function initAccessControls(address _admin) public { 32 | require(!initAccess, "Already initialised"); 33 | _setupRole(DEFAULT_ADMIN_ROLE, _admin); 34 | initAccess = true; 35 | } 36 | 37 | ///////////// 38 | // Lookups // 39 | ///////////// 40 | 41 | /** 42 | * @notice Used to check whether an address has the admin role. 43 | * @param _address EOA or contract being checked. 44 | * @return bool True if the account has the role or false if it does not. 45 | */ 46 | function hasAdminRole(address _address) public view returns (bool) { 47 | return hasRole(DEFAULT_ADMIN_ROLE, _address); 48 | } 49 | 50 | /////////////// 51 | // Modifiers // 52 | /////////////// 53 | 54 | /** 55 | * @notice Grants the admin role to an address. 56 | * @dev The sender must have the admin role. 57 | * @param _address EOA or contract receiving the new role. 58 | */ 59 | function addAdminRole(address _address) external { 60 | grantRole(DEFAULT_ADMIN_ROLE, _address); 61 | emit AdminRoleGranted(_address, _msgSender()); 62 | } 63 | 64 | /** 65 | * @notice Removes the admin role from an address. 66 | * @dev The sender must have the admin role. 67 | * @param _address EOA or contract affected. 68 | */ 69 | function removeAdminRole(address _address) external { 70 | revokeRole(DEFAULT_ADMIN_ROLE, _address); 71 | emit AdminRoleRemoved(_address, _msgSender()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /contracts/Utils/BoringOwnable.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity 0.6.12; 3 | 4 | // Audit on 5-Jan-2021 by Keno and BoringCrypto 5 | // Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol + Claimable.sol 6 | // Edited by BoringCrypto 7 | 8 | contract BoringOwnableData { 9 | address public owner; 10 | address public pendingOwner; 11 | } 12 | 13 | contract BoringOwnable is BoringOwnableData { 14 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 15 | 16 | /// @notice `owner` defaults to msg.sender on construction. 17 | constructor() public { 18 | owner = msg.sender; 19 | emit OwnershipTransferred(address(0), msg.sender); 20 | } 21 | 22 | /// @notice Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner. 23 | /// Can only be invoked by the current `owner`. 24 | /// @param newOwner Address of the new owner. 25 | /// @param direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`. 26 | /// @param renounce Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise. 27 | function transferOwnership( 28 | address newOwner, 29 | bool direct, 30 | bool renounce 31 | ) public onlyOwner { 32 | if (direct) { 33 | // Checks 34 | require(newOwner != address(0) || renounce, "Ownable: zero address"); 35 | 36 | // Effects 37 | emit OwnershipTransferred(owner, newOwner); 38 | owner = newOwner; 39 | pendingOwner = address(0); 40 | } else { 41 | // Effects 42 | pendingOwner = newOwner; 43 | } 44 | } 45 | 46 | /// @notice Needs to be called by `pendingOwner` to claim ownership. 47 | function claimOwnership() public { 48 | address _pendingOwner = pendingOwner; 49 | 50 | // Checks 51 | require(msg.sender == _pendingOwner, "Ownable: caller != pending owner"); 52 | 53 | // Effects 54 | emit OwnershipTransferred(owner, _pendingOwner); 55 | owner = _pendingOwner; 56 | pendingOwner = address(0); 57 | } 58 | 59 | /// @notice Only allows the `owner` to execute the function. 60 | modifier onlyOwner() { 61 | require(msg.sender == owner, "Ownable: caller is not the owner"); 62 | _; 63 | } 64 | } -------------------------------------------------------------------------------- /contracts/OpenZeppelin/access/Ownable.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "../utils/Context.sol"; 6 | /** 7 | * @dev Contract module which provides a basic access control mechanism, where 8 | * there is an account (an owner) that can be granted exclusive access to 9 | * specific functions. 10 | * 11 | * By default, the owner account will be the one that deploys the contract. This 12 | * can later be changed with {transferOwnership}. 13 | * 14 | * This module is used through inheritance. It will make available the modifier 15 | * `onlyOwner`, which can be applied to your functions to restrict their use to 16 | * the owner. 17 | */ 18 | abstract contract Ownable is Context { 19 | address private _owner; 20 | 21 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 22 | 23 | /** 24 | * @dev Initializes the contract setting the deployer as the initial owner. 25 | */ 26 | constructor () internal { 27 | address msgSender = _msgSender(); 28 | _owner = msgSender; 29 | emit OwnershipTransferred(address(0), msgSender); 30 | } 31 | 32 | /** 33 | * @dev Returns the address of the current owner. 34 | */ 35 | function owner() public view virtual returns (address) { 36 | return _owner; 37 | } 38 | 39 | /** 40 | * @dev Throws if called by any account other than the owner. 41 | */ 42 | modifier onlyOwner() { 43 | require(owner() == _msgSender(), "Ownable: caller is not the owner"); 44 | _; 45 | } 46 | 47 | /** 48 | * @dev Leaves the contract without owner. It will not be possible to call 49 | * `onlyOwner` functions anymore. Can only be called by the current owner. 50 | * 51 | * NOTE: Renouncing ownership will leave the contract without an owner, 52 | * thereby removing any functionality that is only available to the owner. 53 | */ 54 | function renounceOwnership() public virtual onlyOwner { 55 | emit OwnershipTransferred(_owner, address(0)); 56 | _owner = address(0); 57 | } 58 | 59 | /** 60 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 61 | * Can only be called by the current owner. 62 | */ 63 | function transferOwnership(address newOwner) public virtual onlyOwner { 64 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 65 | emit OwnershipTransferred(_owner, newOwner); 66 | _owner = newOwner; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /contracts/UniswapV2/UniswapV2Factory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.6.12; 2 | 3 | import './interfaces/IUniswapV2Factory.sol'; 4 | import './UniswapV2Pair.sol'; 5 | 6 | contract UniswapV2Factory is IUniswapV2Factory { 7 | address public override feeTo; 8 | address public override feeToSetter; 9 | address public override migrator; 10 | 11 | mapping(address => mapping(address => address)) public override getPair; 12 | address[] public override allPairs; 13 | 14 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 15 | 16 | constructor(address _feeToSetter) public { 17 | feeToSetter = _feeToSetter; 18 | } 19 | 20 | function allPairsLength() external override view returns (uint) { 21 | return allPairs.length; 22 | } 23 | 24 | function pairCodeHash() external override pure returns (bytes32) { 25 | return keccak256(type(UniswapV2Pair).creationCode); 26 | } 27 | 28 | function createPair(address tokenA, address tokenB) external override returns (address pair) { 29 | require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES'); 30 | (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); 31 | require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS'); 32 | require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient 33 | bytes memory bytecode = type(UniswapV2Pair).creationCode; 34 | bytes32 salt = keccak256(abi.encodePacked(token0, token1)); 35 | assembly { 36 | pair := create2(0, add(bytecode, 32), mload(bytecode), salt) 37 | } 38 | UniswapV2Pair(pair).initialize(token0, token1); 39 | getPair[token0][token1] = pair; 40 | getPair[token1][token0] = pair; // populate mapping in the reverse direction 41 | allPairs.push(pair); 42 | emit PairCreated(token0, token1, pair, allPairs.length); 43 | } 44 | 45 | function setFeeTo(address _feeTo) external override { 46 | require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); 47 | feeTo = _feeTo; 48 | } 49 | 50 | function setMigrator(address _migrator) external override { 51 | require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); 52 | migrator = _migrator; 53 | } 54 | 55 | function setFeeToSetter(address _feeToSetter) external override { 56 | require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); 57 | feeToSetter = _feeToSetter; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /contracts/OpenZeppelin/utils/Pausable.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "./Context.sol"; 6 | 7 | /** 8 | * @dev Contract module which allows children to implement an emergency stop 9 | * mechanism that can be triggered by an authorized account. 10 | * 11 | * This module is used through inheritance. It will make available the 12 | * modifiers `whenNotPaused` and `whenPaused`, which can be applied to 13 | * the functions of your contract. Note that they will not be pausable by 14 | * simply including this module, only once the modifiers are put in place. 15 | */ 16 | abstract contract Pausable is Context { 17 | /** 18 | * @dev Emitted when the pause is triggered by `account`. 19 | */ 20 | event Paused(address account); 21 | 22 | /** 23 | * @dev Emitted when the pause is lifted by `account`. 24 | */ 25 | event Unpaused(address account); 26 | 27 | bool private _paused; 28 | 29 | /** 30 | * @dev Initializes the contract in unpaused state. 31 | */ 32 | constructor () internal { 33 | _paused = false; 34 | } 35 | 36 | /** 37 | * @dev Returns true if the contract is paused, and false otherwise. 38 | */ 39 | function paused() public view virtual returns (bool) { 40 | return _paused; 41 | } 42 | 43 | /** 44 | * @dev Modifier to make a function callable only when the contract is not paused. 45 | * 46 | * Requirements: 47 | * 48 | * - The contract must not be paused. 49 | */ 50 | modifier whenNotPaused() { 51 | require(!paused(), "Pausable: paused"); 52 | _; 53 | } 54 | 55 | /** 56 | * @dev Modifier to make a function callable only when the contract is paused. 57 | * 58 | * Requirements: 59 | * 60 | * - The contract must be paused. 61 | */ 62 | modifier whenPaused() { 63 | require(paused(), "Pausable: not paused"); 64 | _; 65 | } 66 | 67 | /** 68 | * @dev Triggers stopped state. 69 | * 70 | * Requirements: 71 | * 72 | * - The contract must not be paused. 73 | */ 74 | function _pause() internal virtual whenNotPaused { 75 | _paused = true; 76 | emit Paused(_msgSender()); 77 | } 78 | 79 | /** 80 | * @dev Returns to normal state. 81 | * 82 | * Requirements: 83 | * 84 | * - The contract must be paused. 85 | */ 86 | function _unpause() internal virtual whenPaused { 87 | _paused = false; 88 | emit Unpaused(_msgSender()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /contracts/UniswapV2/interfaces/IUniswapV2Pair.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IUniswapV2Pair { 4 | event Approval(address indexed owner, address indexed spender, uint value); 5 | event Transfer(address indexed from, address indexed to, uint value); 6 | 7 | function name() external pure returns (string memory); 8 | function symbol() external pure returns (string memory); 9 | function decimals() external pure returns (uint8); 10 | function totalSupply() external view returns (uint); 11 | function balanceOf(address owner) external view returns (uint); 12 | function allowance(address owner, address spender) external view returns (uint); 13 | 14 | function approve(address spender, uint value) external returns (bool); 15 | function transfer(address to, uint value) external returns (bool); 16 | function transferFrom(address from, address to, uint value) external returns (bool); 17 | 18 | function DOMAIN_SEPARATOR() external view returns (bytes32); 19 | function PERMIT_TYPEHASH() external pure returns (bytes32); 20 | function nonces(address owner) external view returns (uint); 21 | 22 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; 23 | 24 | event Mint(address indexed sender, uint amount0, uint amount1); 25 | event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); 26 | event Swap( 27 | address indexed sender, 28 | uint amount0In, 29 | uint amount1In, 30 | uint amount0Out, 31 | uint amount1Out, 32 | address indexed to 33 | ); 34 | event Sync(uint112 reserve0, uint112 reserve1); 35 | 36 | function MINIMUM_LIQUIDITY() external pure returns (uint); 37 | function factory() external view returns (address); 38 | function token0() external view returns (address); 39 | function token1() external view returns (address); 40 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 41 | function price0CumulativeLast() external view returns (uint); 42 | function price1CumulativeLast() external view returns (uint); 43 | function kLast() external view returns (uint); 44 | 45 | function mint(address to) external returns (uint liquidity); 46 | function burn(address to) external returns (uint amount0, uint amount1); 47 | function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; 48 | function skim(address to) external; 49 | function sync() external; 50 | 51 | function initialize(address, address) external; 52 | } -------------------------------------------------------------------------------- /spec/dutchAuctionCurrentPrice.spec: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a specification file for the formal verification 3 | * of the DutchAuction (priceFunction) using the Certora Prover. 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////// 7 | // Rules // 8 | ////////////////////////////////////////////////////////////////////// 9 | 10 | // priceFunction is always at least minimumPrice and not more than startPrice 11 | rule currentPriceVal() { 12 | env e; 13 | 14 | uint128 startPrice; 15 | uint128 minimumPrice; 16 | uint64 startTime; 17 | uint64 endTime; 18 | uint128 totalTokens; 19 | 20 | startTime, endTime, totalTokens = marketInfo(e); 21 | startPrice, minimumPrice = marketPrice(e); 22 | 23 | require (startTime < endTime && minimumPrice > 0 && startPrice > minimumPrice); 24 | 25 | uint256 pricedrop = priceDrop(e); 26 | require pricedrop > 0; 27 | 28 | uint256 currentPrice = priceFunction(e); 29 | 30 | assert minimumPrice <= currentPrice && currentPrice <= startPrice; 31 | } 32 | 33 | // priceFunction is monotonically decreasing (on a bigger timestamp, the price is lower) 34 | rule priceFunctionDecreasesMonotonically() { 35 | env e1; 36 | env e2; 37 | 38 | uint128 startPrice; 39 | uint128 minimumPrice; 40 | uint64 startTime; 41 | uint64 endTime; 42 | uint128 totalTokens; 43 | 44 | startTime, endTime, totalTokens = marketInfo(e1); 45 | startPrice, minimumPrice = marketPrice(e1); 46 | 47 | require (startTime < endTime && minimumPrice > 0 && startPrice > minimumPrice && isInitialized(e1)); 48 | require e1.block.timestamp <= e2.block.timestamp; 49 | 50 | uint256 _priceFunction = priceFunction(e1); 51 | uint256 priceFunction_ = priceFunction(e2); 52 | 53 | assert (priceFunction_ <= _priceFunction); 54 | } 55 | 56 | // tokenPrice is monotonically increasing (on a bigger timestamp, the price is higher) 57 | rule tokenPriceIncreasesMonotonically(method f) filtered {f -> f.selector != batch(bytes[], bool).selector} { 58 | env e1; 59 | env e2; 60 | 61 | uint128 startPrice; 62 | uint128 minimumPrice; 63 | uint64 startTime; 64 | uint64 endTime; 65 | uint128 totalTokens; 66 | 67 | startTime, endTime, totalTokens = marketInfo(e1); 68 | startPrice, minimumPrice = marketPrice(e1); 69 | 70 | require (startTime < endTime && minimumPrice > 0 && startPrice > minimumPrice && isInitialized(e1)); 71 | require e1.block.timestamp <= e2.block.timestamp; 72 | 73 | uint256 _tokenPrice = tokenPrice(e1); 74 | 75 | calldataarg args; 76 | f(e1, args); 77 | 78 | uint256 tokenPrice_ = tokenPrice(e2); 79 | 80 | assert (_tokenPrice <= tokenPrice_); 81 | } -------------------------------------------------------------------------------- /contracts/Utils/SafeMathPlus.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | /** 4 | * @dev Wrappers over Solidity's arithmetic operations with added overflow 5 | * checks. 6 | * 7 | * SafeMath + plus min(), max() and square root functions 8 | * (square root needs 10*9 factor if using 18 decimals) 9 | * See: https://github.com/OpenZeppelin/openzeppelin-contracts 10 | */ 11 | library SafeMathPlus { 12 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 13 | uint256 c = a + b; 14 | require(c >= a, "SafeMath: addition overflow"); 15 | return c; 16 | } 17 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 18 | return sub(a, b, "SafeMath: subtraction overflow"); 19 | } 20 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 21 | require(b <= a, errorMessage); 22 | uint256 c = a - b; 23 | return c; 24 | } 25 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 26 | if (a == 0) { 27 | return 0; 28 | } 29 | uint256 c = a * b; 30 | require(c / a == b, "SafeMath: multiplication overflow"); 31 | return c; 32 | } 33 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 34 | return div(a, b, "SafeMath: division by zero"); 35 | } 36 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 37 | require(b > 0, errorMessage); 38 | uint256 c = a / b; 39 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 40 | return c; 41 | } 42 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 43 | return mod(a, b, "SafeMath: modulo by zero"); 44 | } 45 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 46 | require(b != 0, errorMessage); 47 | return a % b; 48 | } 49 | function max(uint256 a, uint256 b) internal pure returns (uint256 c) { 50 | c = a >= b ? a : b; 51 | } 52 | function min(uint256 a, uint256 b) internal pure returns (uint256 c) { 53 | c = a <= b ? a : b; 54 | } 55 | // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) 56 | function sqrt(uint y) internal pure returns (uint z) { 57 | if (y > 3) { 58 | z = y; 59 | uint x = y / 2 + 1; 60 | while (x < z) { 61 | z = x; 62 | x = (y / x + x) / 2; 63 | } 64 | } else if (y != 0) { 65 | z = 1; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /contracts/Utils/BoringFactory.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity 0.6.12; 3 | import "../interfaces/IMasterContract.sol"; 4 | 5 | // solhint-disable no-inline-assembly 6 | 7 | contract BoringFactory { 8 | event LogDeploy(address indexed masterContract, bytes data, address indexed cloneAddress); 9 | 10 | /// @notice Mapping from clone contracts to their masterContract. 11 | mapping(address => address) public masterContractOf; 12 | 13 | /// @notice Deploys a given master Contract as a clone. 14 | /// Any ETH transferred with this call is forwarded to the new clone. 15 | /// Emits `LogDeploy`. 16 | /// @param masterContract The address of the contract to clone. 17 | /// @param data Additional abi encoded calldata that is passed to the new clone via `IMasterContract.init`. 18 | /// @param useCreate2 Creates the clone by using the CREATE2 opcode, in this case `data` will be used as salt. 19 | /// @return cloneAddress Address of the created clone contract. 20 | function deploy( 21 | address masterContract, 22 | bytes calldata data, 23 | bool useCreate2 24 | ) public payable returns (address cloneAddress) { 25 | require(masterContract != address(0), "BoringFactory: No masterContract"); 26 | bytes20 targetBytes = bytes20(masterContract); // Takes the first 20 bytes of the masterContract's address 27 | 28 | if (useCreate2) { 29 | // each masterContract has different code already. So clones are distinguished by their data only. 30 | bytes32 salt = keccak256(data); 31 | 32 | // Creates clone, more info here: https://blog.openzeppelin.com/deep-dive-into-the-minimal-proxy-contract/ 33 | assembly { 34 | let clone := mload(0x40) 35 | mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) 36 | mstore(add(clone, 0x14), targetBytes) 37 | mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) 38 | cloneAddress := create2(0, clone, 0x37, salt) 39 | } 40 | } else { 41 | assembly { 42 | let clone := mload(0x40) 43 | mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) 44 | mstore(add(clone, 0x14), targetBytes) 45 | mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) 46 | cloneAddress := create(0, clone, 0x37) 47 | } 48 | } 49 | masterContractOf[cloneAddress] = masterContract; 50 | 51 | IMasterContract(cloneAddress).init{value: msg.value}(data); 52 | 53 | emit LogDeploy(masterContract, data, cloneAddress); 54 | } 55 | } -------------------------------------------------------------------------------- /contracts/OpenZeppelin/utils/ReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | /** 6 | * @dev Contract module that helps prevent reentrant calls to a function. 7 | * 8 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 9 | * available, which can be applied to functions to make sure there are no nested 10 | * (reentrant) calls to them. 11 | * 12 | * Note that because there is a single `nonReentrant` guard, functions marked as 13 | * `nonReentrant` may not call one another. This can be worked around by making 14 | * those functions `private`, and then adding `external` `nonReentrant` entry 15 | * points to them. 16 | * 17 | * TIP: If you would like to learn more about reentrancy and alternative ways 18 | * to protect against it, check out our blog post 19 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 20 | */ 21 | abstract contract ReentrancyGuard { 22 | // Booleans are more expensive than uint256 or any type that takes up a full 23 | // word because each write operation emits an extra SLOAD to first read the 24 | // slot's contents, replace the bits taken up by the boolean, and then write 25 | // back. This is the compiler's defense against contract upgrades and 26 | // pointer aliasing, and it cannot be disabled. 27 | 28 | // The values being non-zero value makes deployment a bit more expensive, 29 | // but in exchange the refund on every call to nonReentrant will be lower in 30 | // amount. Since refunds are capped to a percentage of the total 31 | // transaction's gas, it is best to keep them low in cases like this one, to 32 | // increase the likelihood of the full refund coming into effect. 33 | uint256 private constant _NOT_ENTERED = 1; 34 | uint256 private constant _ENTERED = 2; 35 | 36 | uint256 private _status; 37 | 38 | constructor () internal { 39 | _status = _NOT_ENTERED; 40 | } 41 | 42 | /** 43 | * @dev Prevents a contract from calling itself, directly or indirectly. 44 | * Calling a `nonReentrant` function from another `nonReentrant` 45 | * function is not supported. It is possible to prevent this from happening 46 | * by making the `nonReentrant` function external, and make it call a 47 | * `private` function that does the actual work. 48 | */ 49 | modifier nonReentrant() { 50 | // On the first call to nonReentrant, _notEntered will be true 51 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 52 | 53 | // Any calls to nonReentrant after this point will fail 54 | _status = _ENTERED; 55 | 56 | _; 57 | 58 | // By storing the original value once again, a refund is triggered (see 59 | // https://eips.ethereum.org/EIPS/eip-2200) 60 | _status = _NOT_ENTERED; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/Utils/CloneFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | // ---------------------------------------------------------------------------- 4 | // CloneFactory.sol 5 | // From 6 | // https://github.com/optionality/clone-factory/blob/32782f82dfc5a00d103a7e61a17a5dedbd1e8e9d/contracts/CloneFactory.sol 7 | // ---------------------------------------------------------------------------- 8 | 9 | /* 10 | The MIT License (MIT) 11 | Copyright (c) 2018 Murray Software, LLC. 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | The above copyright notice and this permission notice shall be included 20 | in all copies or substantial portions of the Software. 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 25 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 27 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | */ 29 | //solhint-disable max-line-length 30 | //solhint-disable no-inline-assembly 31 | 32 | contract CloneFactory { 33 | 34 | function createClone(address target) internal returns (address result) { 35 | bytes20 targetBytes = bytes20(target); 36 | assembly { 37 | let clone := mload(0x40) 38 | mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) 39 | mstore(add(clone, 0x14), targetBytes) 40 | mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) 41 | result := create(0, clone, 0x37) 42 | } 43 | } 44 | 45 | function isClone(address target, address query) internal view returns (bool result) { 46 | bytes20 targetBytes = bytes20(target); 47 | assembly { 48 | let clone := mload(0x40) 49 | mstore(clone, 0x363d3d373d3d3d363d7300000000000000000000000000000000000000000000) 50 | mstore(add(clone, 0xa), targetBytes) 51 | mstore(add(clone, 0x1e), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) 52 | 53 | let other := add(clone, 0x40) 54 | extcodecopy(query, other, 0, 0x2d) 55 | result := and( 56 | eq(mload(clone), mload(other)), 57 | eq(mload(add(clone, 0xd)), mload(add(other, 0xd))) 58 | ) 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/Utils/WETH9.sol: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2015, 2016, 2017 Dapphub 2 | 3 | // This program is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License for more details. 12 | 13 | // You should have received a copy of the GNU General Public License 14 | // along with this program. If not, see . 15 | 16 | pragma solidity 0.6.12; 17 | 18 | contract WETH9 { 19 | string public name = "Wrapped Ether"; 20 | string public symbol = "WETH"; 21 | uint8 public decimals = 18; 22 | 23 | event Approval(address indexed src, address indexed guy, uint wad); 24 | event Transfer(address indexed src, address indexed dst, uint wad); 25 | event Deposit(address indexed dst, uint wad); 26 | event Withdrawal(address indexed src, uint wad); 27 | 28 | mapping (address => uint) public balanceOf; 29 | mapping (address => mapping (address => uint)) public allowance; 30 | 31 | receive() external payable { 32 | deposit(); 33 | } 34 | function deposit() public payable { 35 | balanceOf[msg.sender] += msg.value; 36 | emit Deposit(msg.sender, msg.value); 37 | } 38 | function withdraw(uint wad) public { 39 | require(balanceOf[msg.sender] >= wad); 40 | balanceOf[msg.sender] -= wad; 41 | msg.sender.transfer(wad); 42 | emit Withdrawal(msg.sender, wad); 43 | } 44 | 45 | function totalSupply() public view returns (uint) { 46 | return address(this).balance; 47 | } 48 | 49 | function approve(address guy, uint wad) public returns (bool) { 50 | allowance[msg.sender][guy] = wad; 51 | emit Approval(msg.sender, guy, wad); 52 | return true; 53 | } 54 | 55 | function transfer(address dst, uint wad) public returns (bool) { 56 | return transferFrom(msg.sender, dst, wad); 57 | } 58 | 59 | function transferFrom(address src, address dst, uint wad) 60 | public 61 | returns (bool) 62 | { 63 | require(balanceOf[src] >= wad); 64 | 65 | if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { 66 | require(allowance[src][msg.sender] >= wad); 67 | allowance[src][msg.sender] -= wad; 68 | } 69 | 70 | balanceOf[src] -= wad; 71 | balanceOf[dst] += wad; 72 | 73 | emit Transfer(src, dst, wad); 74 | 75 | return true; 76 | } 77 | } 78 | 79 | 80 | -------------------------------------------------------------------------------- /tests/test_master_chef.py: -------------------------------------------------------------------------------- 1 | from brownie import accounts, web3, Wei, reverts, chain 2 | from brownie.network.transaction import TransactionReceipt 3 | from brownie.convert import to_address 4 | import pytest 5 | from brownie import Contract 6 | from settings import * 7 | 8 | TOKEN_1_AMOUNT = 10000 9 | TOTAL_LP_AMOUNT = 10000000000 10 | 11 | @pytest.fixture(scope='function') 12 | def token_1(FixedToken): 13 | token = FixedToken.deploy({'from': accounts[0]}) 14 | name = "Token 1" 15 | symbol = "T1" 16 | owner = accounts[0] 17 | 18 | token.initToken(name, symbol, owner, TOKEN_1_AMOUNT, {'from': owner}) 19 | 20 | return token 21 | 22 | @pytest.fixture(scope='function') 23 | def fake_lp_token(FixedToken): 24 | lp_token = FixedToken.deploy({'from': accounts[0]}) 25 | name = "LP Token" 26 | symbol = "LPT" 27 | owner = accounts[0] 28 | 29 | lp_token.initToken(name, symbol, owner, TOTAL_LP_AMOUNT, {'from': owner}) 30 | 31 | lp_token.transfer(accounts[1], 1000, {'from': owner}) 32 | lp_token.transfer(accounts[2], 1000, {'from': owner}) 33 | lp_token.transfer(accounts[3], 1000, {'from': owner}) 34 | 35 | return lp_token 36 | 37 | 38 | @pytest.fixture(scope='function') 39 | def farm(MISOMasterChef, farm_factory, farm_template, token_1, fake_lp_token): 40 | rewards_per_block = 1 * TENPOW18 41 | # Define the start time relative to sales 42 | start_block = len(chain) + 10 43 | wallet = accounts[4] 44 | dev_addr = wallet 45 | admin = accounts[1] 46 | token_1.approve(farm_factory, TOTAL_LP_AMOUNT, {"from": accounts[0]}) 47 | 48 | data = farm_template.getInitData(token_1, rewards_per_block, start_block, dev_addr, admin) 49 | tx = farm_factory.createFarm(1, wallet, data, {"from": accounts[0]}) 50 | 51 | assert "FarmCreated" in tx.events 52 | farm_address = tx.events["FarmCreated"]["addr"] 53 | farm = MISOMasterChef.at(farm_address) 54 | 55 | assert farm.rewards() == token_1 56 | assert farm.rewardsPerBlock() == rewards_per_block 57 | assert farm.startBlock() == start_block 58 | assert farm.devaddr() == dev_addr 59 | 60 | fake_lp_token.approve(farm, 90, {"from": accounts[0]}) 61 | 62 | farm.addToken(100, fake_lp_token, True, {"from": admin}) 63 | 64 | assert farm.poolInfo(0)[0] == fake_lp_token 65 | assert farm.poolInfo(0)[1] == 100 66 | 67 | return farm 68 | 69 | def test_deposit(farm, fake_lp_token): 70 | fake_lp_token.approve(farm, 1000, {'from': accounts[1]}) 71 | 72 | farm.deposit(0, 100, {'from': accounts[1]}) 73 | 74 | assert fake_lp_token.balanceOf(accounts[1]) == 900 75 | 76 | 77 | def test_emergencyWithdraw(farm, fake_lp_token): 78 | fake_lp_token.approve(farm, 1000, {'from': accounts[1]}) 79 | 80 | farm.deposit(0, 100, {'from': accounts[1]}) 81 | 82 | assert fake_lp_token.balanceOf(accounts[1]) == 900 83 | 84 | farm.emergencyWithdraw(0, {'from': accounts[1]}) 85 | assert fake_lp_token.balanceOf(accounts[1]) == 1000 86 | -------------------------------------------------------------------------------- /contracts/Access/PointList.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | /** 4 | * @dev GP Make a whitelist but instead of adding and removing, set an uint amount for a address 5 | * @dev mapping(address => uint256) public points; 6 | * @dev This amount can be added or removed by an operator 7 | * @dev There is a total points preserved 8 | * @dev Can update an array of points 9 | */ 10 | 11 | import "../OpenZeppelin/math/SafeMath.sol"; 12 | import "./MISOAccessControls.sol"; 13 | import "../interfaces/IPointList.sol"; 14 | 15 | 16 | contract PointList is IPointList, MISOAccessControls { 17 | using SafeMath for uint; 18 | 19 | /// @notice Maping an address to a number fo points. 20 | mapping(address => uint256) public points; 21 | 22 | /// @notice Number of total points. 23 | uint256 public totalPoints; 24 | 25 | /// @notice Event emitted when points are updated. 26 | event PointsUpdated(address indexed account, uint256 oldPoints, uint256 newPoints); 27 | 28 | 29 | constructor() public { 30 | } 31 | 32 | /** 33 | * @notice Initializes point list with admin address. 34 | * @param _admin Admins address. 35 | */ 36 | function initPointList(address _admin) public override { 37 | initAccessControls(_admin); 38 | } 39 | 40 | /** 41 | * @notice Checks if account address is in the list (has any points). 42 | * @param _account Account address. 43 | * @return bool True or False. 44 | */ 45 | function isInList(address _account) public view override returns (bool) { 46 | return points[_account] > 0 ; 47 | } 48 | 49 | /** 50 | * @notice Checks if account has more or equal points as the number given. 51 | * @param _account Account address. 52 | * @param _amount Desired amount of points. 53 | * @return bool True or False. 54 | */ 55 | function hasPoints(address _account, uint256 _amount) public view override returns (bool) { 56 | return points[_account] >= _amount ; 57 | } 58 | 59 | /** 60 | * @notice Sets points to accounts in one batch. 61 | * @param _accounts An array of accounts. 62 | * @param _amounts An array of corresponding amounts. 63 | */ 64 | function setPoints(address[] memory _accounts, uint256[] memory _amounts) external override { 65 | require(hasAdminRole(msg.sender) || hasOperatorRole(msg.sender), "PointList.setPoints: Sender must be operator"); 66 | require(_accounts.length != 0); 67 | require(_accounts.length == _amounts.length); 68 | for (uint i = 0; i < _accounts.length; i++) { 69 | address account = _accounts[i]; 70 | uint256 amount = _amounts[i]; 71 | uint256 previousPoints = points[account]; 72 | 73 | if (amount != previousPoints) { 74 | points[account] = amount; 75 | totalPoints = totalPoints.sub(previousPoints).add(amount); 76 | emit PointsUpdated(account, previousPoints, amount); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /contracts/OpenZeppelin/math/SignedSafeMath.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity 0.6.12; 3 | 4 | library SignedSafeMath { 5 | int256 constant private _INT256_MIN = -2**255; 6 | 7 | /** 8 | * @dev Returns the multiplication of two signed integers, reverting on 9 | * overflow. 10 | * 11 | * Counterpart to Solidity's `*` operator. 12 | * 13 | * Requirements: 14 | * 15 | * - Multiplication cannot overflow. 16 | */ 17 | function mul(int256 a, int256 b) internal pure returns (int256) { 18 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 19 | // benefit is lost if 'b' is also tested. 20 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 21 | if (a == 0) { 22 | return 0; 23 | } 24 | 25 | require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow"); 26 | 27 | int256 c = a * b; 28 | require(c / a == b, "SignedSafeMath: multiplication overflow"); 29 | 30 | return c; 31 | } 32 | 33 | /** 34 | * @dev Returns the integer division of two signed integers. Reverts on 35 | * division by zero. The result is rounded towards zero. 36 | * 37 | * Counterpart to Solidity's `/` operator. Note: this function uses a 38 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 39 | * uses an invalid opcode to revert (consuming all remaining gas). 40 | * 41 | * Requirements: 42 | * 43 | * - The divisor cannot be zero. 44 | */ 45 | function div(int256 a, int256 b) internal pure returns (int256) { 46 | require(b != 0, "SignedSafeMath: division by zero"); 47 | require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow"); 48 | 49 | int256 c = a / b; 50 | 51 | return c; 52 | } 53 | 54 | /** 55 | * @dev Returns the subtraction of two signed integers, reverting on 56 | * overflow. 57 | * 58 | * Counterpart to Solidity's `-` operator. 59 | * 60 | * Requirements: 61 | * 62 | * - Subtraction cannot overflow. 63 | */ 64 | function sub(int256 a, int256 b) internal pure returns (int256) { 65 | int256 c = a - b; 66 | require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow"); 67 | 68 | return c; 69 | } 70 | 71 | /** 72 | * @dev Returns the addition of two signed integers, reverting on 73 | * overflow. 74 | * 75 | * Counterpart to Solidity's `+` operator. 76 | * 77 | * Requirements: 78 | * 79 | * - Addition cannot overflow. 80 | */ 81 | function add(int256 a, int256 b) internal pure returns (int256) { 82 | int256 c = a + b; 83 | require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow"); 84 | 85 | return c; 86 | } 87 | 88 | function toUInt256(int256 a) internal pure returns (uint256) { 89 | require(a >= 0, "Integer < 0"); 90 | return uint256(a); 91 | } 92 | } -------------------------------------------------------------------------------- /contracts/Utils/BoringBatchable.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity 0.6.12; 3 | pragma experimental ABIEncoderV2; 4 | 5 | // solhint-disable avoid-low-level-calls 6 | // solhint-disable no-inline-assembly 7 | 8 | // Audit on 5-Jan-2021 by Keno and BoringCrypto 9 | 10 | import "./BoringERC20.sol"; 11 | 12 | contract BaseBoringBatchable { 13 | /// @dev Helper function to extract a useful revert message from a failed call. 14 | /// If the returned data is malformed or not correctly abi encoded then this call can fail itself. 15 | function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) { 16 | // If the _res length is less than 68, then the transaction failed silently (without a revert message) 17 | if (_returnData.length < 68) return "Transaction reverted silently"; 18 | 19 | assembly { 20 | // Slice the sighash. 21 | _returnData := add(_returnData, 0x04) 22 | } 23 | return abi.decode(_returnData, (string)); // All that remains is the revert string 24 | } 25 | 26 | /// @notice Allows batched call to self (this contract). 27 | /// @param calls An array of inputs for each call. 28 | /// @param revertOnFail If True then reverts after a failed call and stops doing further calls. 29 | /// @return successes An array indicating the success of a call, mapped one-to-one to `calls`. 30 | /// @return results An array with the returned data of each function call, mapped one-to-one to `calls`. 31 | // F1: External is ok here because this is the batch function, adding it to a batch makes no sense 32 | // F2: Calls in the batch may be payable, delegatecall operates in the same context, so each call in the batch has access to msg.value 33 | // C3: The length of the loop is fully under user control, so can't be exploited 34 | // C7: Delegatecall is only used on the same contract, so it's safe 35 | function batch(bytes[] calldata calls, bool revertOnFail) external payable returns (bool[] memory successes, bytes[] memory results) { 36 | successes = new bool[](calls.length); 37 | results = new bytes[](calls.length); 38 | for (uint256 i = 0; i < calls.length; i++) { 39 | (bool success, bytes memory result) = address(this).delegatecall(calls[i]); 40 | require(success || !revertOnFail, _getRevertMsg(result)); 41 | successes[i] = success; 42 | results[i] = result; 43 | } 44 | } 45 | } 46 | 47 | contract BoringBatchable is BaseBoringBatchable { 48 | /// @notice Call wrapper that performs `ERC20.permit` on `token`. 49 | /// Lookup `IERC20.permit`. 50 | // F6: Parameters can be used front-run the permit and the user's permit will fail (due to nonce or other revert) 51 | // if part of a batch this could be used to grief once as the second call would not need the permit 52 | function permitToken( 53 | IERC20 token, 54 | address from, 55 | address to, 56 | uint256 amount, 57 | uint256 deadline, 58 | uint8 v, 59 | bytes32 r, 60 | bytes32 s 61 | ) public { 62 | token.permit(from, to, amount, deadline, v, r, s); 63 | } 64 | } -------------------------------------------------------------------------------- /contracts/Utils/BoringMath.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity 0.6.12; 3 | 4 | /// @notice A library for performing overflow-/underflow-safe math, 5 | /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). 6 | library BoringMath { 7 | function add(uint256 a, uint256 b) internal pure returns (uint256 c) { 8 | require((c = a + b) >= b, "BoringMath: Add Overflow"); 9 | } 10 | 11 | function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { 12 | require((c = a - b) <= a, "BoringMath: Underflow"); 13 | } 14 | 15 | function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { 16 | require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); 17 | } 18 | 19 | function div(uint256 a, uint256 b) internal pure returns (uint256 c) { 20 | require(b > 0, "BoringMath: Div zero"); 21 | c = a / b; 22 | } 23 | 24 | function to128(uint256 a) internal pure returns (uint128 c) { 25 | require(a <= uint128(-1), "BoringMath: uint128 Overflow"); 26 | c = uint128(a); 27 | } 28 | 29 | function to64(uint256 a) internal pure returns (uint64 c) { 30 | require(a <= uint64(-1), "BoringMath: uint64 Overflow"); 31 | c = uint64(a); 32 | } 33 | 34 | function to32(uint256 a) internal pure returns (uint32 c) { 35 | require(a <= uint32(-1), "BoringMath: uint32 Overflow"); 36 | c = uint32(a); 37 | } 38 | 39 | function to16(uint256 a) internal pure returns (uint16 c) { 40 | require(a <= uint16(-1), "BoringMath: uint16 Overflow"); 41 | c = uint16(a); 42 | } 43 | 44 | } 45 | 46 | /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint128. 47 | library BoringMath128 { 48 | function add(uint128 a, uint128 b) internal pure returns (uint128 c) { 49 | require((c = a + b) >= b, "BoringMath: Add Overflow"); 50 | } 51 | 52 | function sub(uint128 a, uint128 b) internal pure returns (uint128 c) { 53 | require((c = a - b) <= a, "BoringMath: Underflow"); 54 | } 55 | } 56 | 57 | /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint64. 58 | library BoringMath64 { 59 | function add(uint64 a, uint64 b) internal pure returns (uint64 c) { 60 | require((c = a + b) >= b, "BoringMath: Add Overflow"); 61 | } 62 | 63 | function sub(uint64 a, uint64 b) internal pure returns (uint64 c) { 64 | require((c = a - b) <= a, "BoringMath: Underflow"); 65 | } 66 | } 67 | 68 | /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. 69 | library BoringMath32 { 70 | function add(uint32 a, uint32 b) internal pure returns (uint32 c) { 71 | require((c = a + b) >= b, "BoringMath: Add Overflow"); 72 | } 73 | 74 | function sub(uint32 a, uint32 b) internal pure returns (uint32 c) { 75 | require((c = a - b) <= a, "BoringMath: Underflow"); 76 | } 77 | } 78 | 79 | /// @notice A library for performing overflow-/underflow-safe addition and subtraction on uint32. 80 | library BoringMath16 { 81 | function add(uint16 a, uint16 b) internal pure returns (uint16 c) { 82 | require((c = a + b) >= b, "BoringMath: Add Overflow"); 83 | } 84 | 85 | function sub(uint16 a, uint16 b) internal pure returns (uint16 c) { 86 | require((c = a - b) <= a, "BoringMath: Underflow"); 87 | } 88 | } -------------------------------------------------------------------------------- /contracts/Utils/BoringERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | import "../interfaces/IERC20.sol"; 3 | 4 | // solhint-disable avoid-low-level-calls 5 | 6 | library BoringERC20 { 7 | bytes4 private constant SIG_SYMBOL = 0x95d89b41; // symbol() 8 | bytes4 private constant SIG_NAME = 0x06fdde03; // name() 9 | bytes4 private constant SIG_DECIMALS = 0x313ce567; // decimals() 10 | bytes4 private constant SIG_TRANSFER = 0xa9059cbb; // transfer(address,uint256) 11 | bytes4 private constant SIG_TRANSFER_FROM = 0x23b872dd; // transferFrom(address,address,uint256) 12 | 13 | /// @notice Provides a safe ERC20.symbol version which returns '???' as fallback string. 14 | /// @param token The address of the ERC-20 token contract. 15 | /// @return (string) Token symbol. 16 | function safeSymbol(IERC20 token) internal view returns (string memory) { 17 | (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_SYMBOL)); 18 | return success && data.length > 0 ? abi.decode(data, (string)) : "???"; 19 | } 20 | 21 | /// @notice Provides a safe ERC20.name version which returns '???' as fallback string. 22 | /// @param token The address of the ERC-20 token contract. 23 | /// @return (string) Token name. 24 | function safeName(IERC20 token) internal view returns (string memory) { 25 | (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_NAME)); 26 | return success && data.length > 0 ? abi.decode(data, (string)) : "???"; 27 | } 28 | 29 | /// @notice Provides a safe ERC20.decimals version which returns '18' as fallback value. 30 | /// @param token The address of the ERC-20 token contract. 31 | /// @return (uint8) Token decimals. 32 | function safeDecimals(IERC20 token) internal view returns (uint8) { 33 | (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(SIG_DECIMALS)); 34 | return success && data.length == 32 ? abi.decode(data, (uint8)) : 18; 35 | } 36 | 37 | /// @notice Provides a safe ERC20.transfer version for different ERC-20 implementations. 38 | /// Reverts on a failed transfer. 39 | /// @param token The address of the ERC-20 token. 40 | /// @param to Transfer tokens to. 41 | /// @param amount The token amount. 42 | function safeTransfer( 43 | IERC20 token, 44 | address to, 45 | uint256 amount 46 | ) internal { 47 | (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(SIG_TRANSFER, to, amount)); 48 | require(success && (data.length == 0 || abi.decode(data, (bool))), "BoringERC20: Transfer failed"); 49 | } 50 | 51 | /// @notice Provides a safe ERC20.transferFrom version for different ERC-20 implementations. 52 | /// Reverts on a failed transfer. 53 | /// @param token The address of the ERC-20 token. 54 | /// @param from Transfer tokens from. 55 | /// @param to Transfer tokens to. 56 | /// @param amount The token amount. 57 | function safeTransferFrom( 58 | IERC20 token, 59 | address from, 60 | address to, 61 | uint256 amount 62 | ) internal { 63 | (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(SIG_TRANSFER_FROM, from, to, amount)); 64 | require(success && (data.length == 0 || abi.decode(data, (bool))), "BoringERC20: TransferFrom failed"); 65 | } 66 | } -------------------------------------------------------------------------------- /spec/dutchAuctionAdditional.spec: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a specification file for the formal verification 3 | * of the DutchAuction using the Certora Prover. These rules take long 4 | * to run, so they are seperated from the main spec file. 5 | */ 6 | 7 | /* 8 | * Declaration of contracts used in the spec 9 | */ 10 | using DummyERC20A as tokenA 11 | using DummyERC20B as tokenB 12 | using DummyWeth as wethTokenImpl 13 | using Receiver as receiver 14 | 15 | /* 16 | * Declaration of methods that are used in the rules. 17 | * envfree indicates that the method is not dependent on the environment, eg: 18 | * msg.value, msg.sender, etc. 19 | * Methods that are not declared here are assumed to be dependent on env. 20 | */ 21 | methods { 22 | // envfree methods 23 | commitments(address) returns (uint256) envfree 24 | paymentCurrency() returns (address) envfree 25 | tokenBalanceOf(address, address) returns (uint256) envfree 26 | getCommitmentsTotal() returns (uint256) envfree 27 | 28 | // IERC20 methods to be called with one of the tokens (DummyERC20*, DummyWeth) 29 | balanceOf(address) => DISPATCHER(true) 30 | totalSupply() => DISPATCHER(true) 31 | transferFrom(address from, address to, uint256 amount) => DISPATCHER(true) 32 | transfer(address to, uint256 amount) => DISPATCHER(true) 33 | permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) => NONDET 34 | decimals() => DISPATCHER(true) 35 | 36 | // receiver if weth 37 | sendTo() => DISPATCHER(true) 38 | 39 | // IPointList 40 | hasPoints(address account, uint256 amount) => NONDET 41 | } 42 | 43 | // Max uint256 value in hex 44 | definition MAX_UNSIGNED_INT() returns uint256 = 45 | 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; 46 | 47 | // commitTokensFrom is additive, meaning that first commiting x, then commiting 48 | // y is same as commiting x + y in one go. 49 | rule additivityOfCommitTokensFrom(uint256 x, uint256 y, 50 | address from, bool agreement) { 51 | env e; 52 | 53 | require e.msg.sender != currentContract; 54 | 55 | // recording the entire state of the contract 56 | storage initStorage = lastStorage; 57 | 58 | // commiting x and y in two steps 59 | commitTokensFrom(e, from, x, agreement); 60 | commitTokensFrom(e, from, y, agreement); 61 | 62 | // recording state when commited using two steps 63 | uint256 splitScenarioCommitment = commitments(from); 64 | uint256 splitScenarioSenderBalanceOf = tokenBalanceOf(paymentCurrency(), e.msg.sender); 65 | uint256 splitTotalCommitments = getCommitmentsTotal(); 66 | 67 | // overflow prevention 68 | require x + y <= MAX_UNSIGNED_INT(); 69 | uint256 sum = x + y; 70 | 71 | // commiting x + y in one step using initStorage 72 | commitTokensFrom(e, from, sum, agreement) at initStorage; 73 | 74 | // recording state when commited using one step 75 | uint256 sumScenarioCommitment = commitments(from); 76 | uint256 sumScenarioSenderBalanceOf = tokenBalanceOf(paymentCurrency(), e.msg.sender); 77 | uint256 sumTotalCommitments = getCommitmentsTotal(); 78 | 79 | // asserting that commiting using two steps is the same as commiting using 80 | // one step 81 | assert(splitScenarioCommitment == sumScenarioCommitment, 82 | "addCommitment not additive on commitment"); 83 | 84 | assert(splitScenarioSenderBalanceOf == sumScenarioSenderBalanceOf, 85 | "addCommitment not additive on sender's balanceOf"); 86 | 87 | assert(splitTotalCommitments == sumTotalCommitments, 88 | "addCommitment not additive on totalCommitments"); 89 | } -------------------------------------------------------------------------------- /contracts/Utils/SafeTransfer.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | contract SafeTransfer { 4 | 5 | address private constant ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; 6 | 7 | /// @dev Helper function to handle both ETH and ERC20 payments 8 | function _safeTokenPayment( 9 | address _token, 10 | address payable _to, 11 | uint256 _amount 12 | ) internal { 13 | if (address(_token) == ETH_ADDRESS) { 14 | _safeTransferETH(_to,_amount ); 15 | } else { 16 | _safeTransfer(_token, _to, _amount); 17 | } 18 | } 19 | 20 | 21 | /// @dev Helper function to handle both ETH and ERC20 payments 22 | function _tokenPayment( 23 | address _token, 24 | address payable _to, 25 | uint256 _amount 26 | ) internal { 27 | if (address(_token) == ETH_ADDRESS) { 28 | _to.transfer(_amount); 29 | } else { 30 | _safeTransfer(_token, _to, _amount); 31 | } 32 | } 33 | 34 | 35 | /// @dev Transfer helper from UniswapV2 Router 36 | function _safeApprove(address token, address to, uint value) internal { 37 | // bytes4(keccak256(bytes('approve(address,uint256)'))); 38 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); 39 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); 40 | } 41 | 42 | 43 | /** 44 | * There are many non-compliant ERC20 tokens... this can handle most, adapted from UniSwap V2 45 | * Im trying to make it a habit to put external calls last (reentrancy) 46 | * You can put this in an internal function if you like. 47 | */ 48 | function _safeTransfer( 49 | address token, 50 | address to, 51 | uint256 amount 52 | ) internal virtual { 53 | // solium-disable-next-line security/no-low-level-calls 54 | (bool success, bytes memory data) = 55 | token.call( 56 | // 0xa9059cbb = bytes4(keccak256("transfer(address,uint256)")) 57 | abi.encodeWithSelector(0xa9059cbb, to, amount) 58 | ); 59 | require(success && (data.length == 0 || abi.decode(data, (bool)))); // ERC20 Transfer failed 60 | } 61 | 62 | function _safeTransferFrom( 63 | address token, 64 | address from, 65 | uint256 amount 66 | ) internal virtual { 67 | // solium-disable-next-line security/no-low-level-calls 68 | (bool success, bytes memory data) = 69 | token.call( 70 | // 0x23b872dd = bytes4(keccak256("transferFrom(address,address,uint256)")) 71 | abi.encodeWithSelector(0x23b872dd, from, address(this), amount) 72 | ); 73 | require(success && (data.length == 0 || abi.decode(data, (bool)))); // ERC20 TransferFrom failed 74 | } 75 | 76 | function _safeTransferFrom(address token, address from, address to, uint value) internal { 77 | // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); 78 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); 79 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); 80 | } 81 | 82 | function _safeTransferETH(address to, uint value) internal { 83 | (bool success,) = to.call{value:value}(new bytes(0)); 84 | require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); 85 | } 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /scripts/deploy_MISO.py: -------------------------------------------------------------------------------- 1 | from brownie import * 2 | from .settings import * 3 | from .contracts import * 4 | from .contract_addresses import * 5 | import time 6 | 7 | 8 | def main(): 9 | load_accounts() 10 | 11 | # Initialise Project 12 | deployer = accounts[0] 13 | admin = accounts[1] 14 | 15 | # When deployed, should the contracts be unlocked? 16 | unlock = True 17 | 18 | # miso access control 19 | access_control = deploy_access_control(deployer) 20 | if access_control.hasAdminRole(admin) == False: 21 | access_control.addAdminRole(admin, {'from': accounts[0]}) 22 | 23 | if access_control.hasAdminRole(deployer) == False: 24 | access_control.addAdminRole(deployer, {'from': admin}) 25 | 26 | # Setup MISOTokenFactory 27 | miso_token_factory = deploy_miso_token_factory(access_control) 28 | fixed_token_template = deploy_fixed_token_template() 29 | mintable_token_template = deploy_mintable_token_template() 30 | 31 | sushi_token_template = deploy_sushi_token_template() 32 | 33 | if miso_token_factory.tokenTemplateId() == 0: 34 | miso_token_factory.addTokenTemplate( 35 | mintable_token_template, {'from': deployer}) 36 | miso_token_factory.addTokenTemplate( 37 | fixed_token_template, {'from': deployer}) 38 | miso_token_factory.addTokenTemplate( 39 | sushi_token_template, {'from': deployer}) 40 | 41 | # Setup MISO Market 42 | bento_box = deploy_bento_box() 43 | crowdsale_template = deploy_crowdsale_template() 44 | dutch_auction_template = deploy_dutch_auction_template() 45 | batch_auction_template = deploy_batch_auction_template() 46 | hyperbolic_auction_template = deploy_hyperbolic_auction_template() 47 | 48 | miso_market = deploy_miso_market(access_control, bento_box, [ 49 | dutch_auction_template, crowdsale_template, batch_auction_template, hyperbolic_auction_template]) 50 | 51 | # Setup PointList 52 | pointlist_template = deploy_pointlist_template() 53 | pointlist_factory = deploy_pointlist_factory( 54 | pointlist_template, access_control, 0) 55 | 56 | # MISOLauncher 57 | weth_token = deploy_weth_token() 58 | 59 | post_auction_template = deploy_post_auction_template(weth_token) 60 | miso_launcher = deploy_miso_launcher(access_control, weth_token, bento_box) 61 | if miso_launcher.launcherTemplateId() == 0: 62 | miso_launcher.addLiquidityLauncherTemplate(post_auction_template, {"from": accounts[0]} ) 63 | 64 | # MISOFarmFactory 65 | masterchef_template = deploy_masterchef_template() 66 | farm_factory = deploy_farm_factory(access_control) 67 | if farm_factory.farmTemplateId() == 0: 68 | farm_factory.addFarmTemplate( 69 | masterchef_template, {"from": accounts[0]}) 70 | 71 | # Helper contract 72 | miso_helper = deploy_miso_helper( 73 | access_control, miso_token_factory, miso_market, miso_launcher, farm_factory) 74 | 75 | # Set Factory lock status 76 | if unlock and miso_market.locked() == True: 77 | miso_market.setLocked(False, {'from': accounts[0]} ) 78 | if unlock and farm_factory.locked() == True: 79 | farm_factory.setLocked(False, {'from': accounts[0]} ) 80 | if unlock and miso_launcher.locked() == True: 81 | miso_launcher.setLocked(False, {'from': accounts[0]} ) 82 | if unlock and miso_token_factory.locked() == True: 83 | miso_token_factory.setLocked(False, {'from': accounts[0]} ) 84 | 85 | # Revoke deployer admin rights 86 | access_control.removeOperatorRole(deployer, {'from': accounts[0]}) 87 | access_control.removeAdminRole(deployer, {'from': accounts[0]}) 88 | -------------------------------------------------------------------------------- /contracts/UniswapV2/UniswapV2ERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity =0.6.12; 2 | 3 | import './libraries/SafeMath.sol'; 4 | 5 | contract UniswapV2ERC20 { 6 | using SafeMathUniswap for uint; 7 | 8 | string public constant name = 'SushiSwap LP Token'; 9 | string public constant symbol = 'SLP'; 10 | uint8 public constant decimals = 18; 11 | uint public totalSupply; 12 | mapping(address => uint) public balanceOf; 13 | mapping(address => mapping(address => uint)) public allowance; 14 | 15 | bytes32 public DOMAIN_SEPARATOR; 16 | // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 17 | bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; 18 | mapping(address => uint) public nonces; 19 | 20 | event Approval(address indexed owner, address indexed spender, uint value); 21 | event Transfer(address indexed from, address indexed to, uint value); 22 | 23 | constructor() public { 24 | uint chainId; 25 | assembly { 26 | chainId := chainid() 27 | } 28 | DOMAIN_SEPARATOR = keccak256( 29 | abi.encode( 30 | keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), 31 | keccak256(bytes(name)), 32 | keccak256(bytes('1')), 33 | chainId, 34 | address(this) 35 | ) 36 | ); 37 | } 38 | 39 | function _mint(address to, uint value) internal { 40 | totalSupply = totalSupply.add(value); 41 | balanceOf[to] = balanceOf[to].add(value); 42 | emit Transfer(address(0), to, value); 43 | } 44 | 45 | function _burn(address from, uint value) internal { 46 | balanceOf[from] = balanceOf[from].sub(value); 47 | totalSupply = totalSupply.sub(value); 48 | emit Transfer(from, address(0), value); 49 | } 50 | 51 | function _approve(address owner, address spender, uint value) private { 52 | allowance[owner][spender] = value; 53 | emit Approval(owner, spender, value); 54 | } 55 | 56 | function _transfer(address from, address to, uint value) private { 57 | balanceOf[from] = balanceOf[from].sub(value); 58 | balanceOf[to] = balanceOf[to].add(value); 59 | emit Transfer(from, to, value); 60 | } 61 | 62 | function approve(address spender, uint value) external returns (bool) { 63 | _approve(msg.sender, spender, value); 64 | return true; 65 | } 66 | 67 | function transfer(address to, uint value) external returns (bool) { 68 | _transfer(msg.sender, to, value); 69 | return true; 70 | } 71 | 72 | function transferFrom(address from, address to, uint value) external returns (bool) { 73 | if (allowance[from][msg.sender] != uint(-1)) { 74 | allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); 75 | } 76 | _transfer(from, to, value); 77 | return true; 78 | } 79 | 80 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { 81 | require(deadline >= block.timestamp, 'UniswapV2: EXPIRED'); 82 | bytes32 digest = keccak256( 83 | abi.encodePacked( 84 | '\x19\x01', 85 | DOMAIN_SEPARATOR, 86 | keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) 87 | ) 88 | ); 89 | address recoveredAddress = ecrecover(digest, v, r, s); 90 | require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE'); 91 | _approve(owner, spender, value); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /tests/test_point_list.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from brownie import accounts, reverts 3 | from settings import * 4 | 5 | # reset the chain after every test case 6 | @pytest.fixture(autouse=True) 7 | def isolation(fn_isolation): 8 | pass 9 | 10 | def test_point_list(point_list): 11 | points = 10 12 | tx = point_list.setPoints([accounts[3]], [points], {"from": accounts[0]}) 13 | assert "PointsUpdated" in tx.events 14 | assert point_list.hasPoints(accounts[3], points) == True 15 | 16 | assert point_list.isInList(accounts[3]) == True 17 | assert point_list.points(accounts[3]) == points 18 | 19 | 20 | def test_point_list_remove(point_list): 21 | points = 10 22 | tx = point_list.setPoints([accounts[3]], [points], {"from": accounts[0]}) 23 | assert point_list.points(accounts[3]) == points 24 | points = 10 25 | tx = point_list.setPoints([accounts[3]], [points], {"from": accounts[0]}) 26 | assert "PointsUpdated" not in tx.events 27 | with reverts(): 28 | tx = point_list.setPoints([], [], {"from": accounts[0]}) 29 | with reverts(): 30 | tx = point_list.setPoints([], [points], {"from": accounts[0]}) 31 | with reverts(): 32 | tx = point_list.setPoints([accounts[3]], [], {"from": accounts[0]}) 33 | with reverts(): 34 | tx = point_list.setPoints([accounts[3]], [points], {"from": accounts[1]}) 35 | 36 | points = 5 37 | tx = point_list.setPoints([accounts[3]], [points], {"from": accounts[0]}) 38 | assert point_list.points(accounts[3]) == points 39 | assert point_list.totalPoints() == points 40 | points = 0 41 | tx = point_list.setPoints([accounts[3]], [points], {"from": accounts[0]}) 42 | assert "PointsUpdated" in tx.events 43 | assert point_list.totalPoints() == 0 44 | assert point_list.points(accounts[3]) == 0 45 | assert point_list.isInList(accounts[3]) == False 46 | assert point_list.hasPoints(accounts[3], 1) == False 47 | 48 | 49 | # Test cannot initPointList twice 50 | # Test not allowed operator, cannot change 51 | # Test setPoints to an empty account array, and empty amount, and both empty 52 | # Test an array with multiple users, some duplicates accounts different amounts 53 | # Test changing amount, higher, lower, higher and check still correct, and totalPoints correct 54 | 55 | def test_init_twice(point_list): 56 | with reverts("Already initialised"): 57 | point_list.initPointList(accounts[0], {"from": accounts[0]}) 58 | 59 | def test_set_points_not_operator(point_list): 60 | points = 10 61 | with reverts("PointList.setPoints: Sender must be operator"): 62 | point_list.setPoints([accounts[3]], [points], {"from": accounts[5]}) 63 | 64 | def test_multiple_accounts_changing_amount(point_list): 65 | points = [5,10] 66 | account = [accounts[5], accounts[6]] 67 | 68 | tx = point_list.setPoints(account, points, {"from": accounts[0]}) 69 | assert "PointsUpdated" in tx.events 70 | totalPoints = 5 + 10 71 | assert point_list.totalPoints() == totalPoints 72 | assert point_list.points(accounts[5]) == 5 73 | assert point_list.points(accounts[6]) == 10 74 | 75 | 76 | points = [15,20] 77 | account = [accounts[7], accounts[8]] 78 | tx = point_list.setPoints(account, points, {"from": accounts[0]}) 79 | assert "PointsUpdated" in tx.events 80 | totalPoints = 5 + 10 + 15 + 20 81 | assert point_list.totalPoints() == totalPoints 82 | assert point_list.points(accounts[7]) == 15 83 | assert point_list.points(accounts[8]) == 20 84 | 85 | points = [10,15] 86 | account = [accounts[5], accounts[6]] 87 | 88 | tx = point_list.setPoints(account, points, {"from": accounts[0]}) 89 | assert "PointsUpdated" in tx.events 90 | totalPoints = totalPoints - 5 - 10 + 10 + 15 91 | assert point_list.totalPoints() == totalPoints 92 | assert point_list.points(accounts[5]) == 10 93 | assert point_list.points(accounts[6]) == 15 94 | -------------------------------------------------------------------------------- /contracts/UniswapV2/interfaces/IUniswapV2Router01.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | interface IUniswapV2Router01 { 4 | function factory() external pure returns (address); 5 | function WETH() external pure returns (address); 6 | 7 | function addLiquidity( 8 | address tokenA, 9 | address tokenB, 10 | uint amountADesired, 11 | uint amountBDesired, 12 | uint amountAMin, 13 | uint amountBMin, 14 | address to, 15 | uint deadline 16 | ) external returns (uint amountA, uint amountB, uint liquidity); 17 | function addLiquidityETH( 18 | address token, 19 | uint amountTokenDesired, 20 | uint amountTokenMin, 21 | uint amountETHMin, 22 | address to, 23 | uint deadline 24 | ) external payable returns (uint amountToken, uint amountETH, uint liquidity); 25 | function removeLiquidity( 26 | address tokenA, 27 | address tokenB, 28 | uint liquidity, 29 | uint amountAMin, 30 | uint amountBMin, 31 | address to, 32 | uint deadline 33 | ) external returns (uint amountA, uint amountB); 34 | function removeLiquidityETH( 35 | address token, 36 | uint liquidity, 37 | uint amountTokenMin, 38 | uint amountETHMin, 39 | address to, 40 | uint deadline 41 | ) external returns (uint amountToken, uint amountETH); 42 | function removeLiquidityWithPermit( 43 | address tokenA, 44 | address tokenB, 45 | uint liquidity, 46 | uint amountAMin, 47 | uint amountBMin, 48 | address to, 49 | uint deadline, 50 | bool approveMax, uint8 v, bytes32 r, bytes32 s 51 | ) external returns (uint amountA, uint amountB); 52 | function removeLiquidityETHWithPermit( 53 | address token, 54 | uint liquidity, 55 | uint amountTokenMin, 56 | uint amountETHMin, 57 | address to, 58 | uint deadline, 59 | bool approveMax, uint8 v, bytes32 r, bytes32 s 60 | ) external returns (uint amountToken, uint amountETH); 61 | function swapExactTokensForTokens( 62 | uint amountIn, 63 | uint amountOutMin, 64 | address[] calldata path, 65 | address to, 66 | uint deadline 67 | ) external returns (uint[] memory amounts); 68 | function swapTokensForExactTokens( 69 | uint amountOut, 70 | uint amountInMax, 71 | address[] calldata path, 72 | address to, 73 | uint deadline 74 | ) external returns (uint[] memory amounts); 75 | function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 76 | external 77 | payable 78 | returns (uint[] memory amounts); 79 | function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 80 | external 81 | returns (uint[] memory amounts); 82 | function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 83 | external 84 | returns (uint[] memory amounts); 85 | function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 86 | external 87 | payable 88 | returns (uint[] memory amounts); 89 | 90 | function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 91 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); 92 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); 93 | function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 94 | function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 95 | } -------------------------------------------------------------------------------- /scripts/deploy_recipe02.py: -------------------------------------------------------------------------------- 1 | from brownie import * 2 | from .settings import * 3 | from .contracts import * 4 | from .contract_addresses import * 5 | import time 6 | 7 | 8 | def main(): 9 | load_accounts() 10 | 11 | # Initialise Project 12 | operator = accounts[0] 13 | wallet = accounts[1] 14 | 15 | # GP: Split into public and miso access control 16 | access_control = deploy_access_control(operator) 17 | user_access_control = deploy_user_access_control(operator) 18 | # user_access_control = access_control 19 | 20 | # Setup MISOTokenFactory 21 | miso_token_factory = deploy_miso_token_factory(access_control) 22 | mintable_token_template = deploy_mintable_token_template() 23 | if miso_token_factory.tokenTemplateId() == 0: 24 | miso_token_factory.addTokenTemplate( 25 | mintable_token_template, {'from': operator}) 26 | 27 | # Setup MISO Market 28 | bento_box = deploy_bento_box() 29 | 30 | crowdsale_template = deploy_crowdsale_template() 31 | dutch_auction_template = deploy_dutch_auction_template() 32 | miso_market = deploy_miso_market( 33 | access_control, [dutch_auction_template, crowdsale_template]) 34 | uniswap_factory = deploy_uniswap_factory() 35 | 36 | # MISOLauncher 37 | weth_token = deploy_weth_token() 38 | 39 | pool_liquidity_template = deploy_pool_liquidity_template() 40 | miso_launcher = deploy_miso_launcher(access_control, weth_token, bento_box) 41 | if miso_launcher.getLiquidityTemplateIndex(0) == ZERO_ADDRESS: 42 | miso_launcher.addLiquidityLauncherTemplate( 43 | pool_liquidity_template, {"from": accounts[0]}) 44 | 45 | # MISOFarmFactory 46 | masterchef_template = deploy_masterchef_template() 47 | farm_factory = deploy_farm_factory(access_control) 48 | if farm_factory.farmTemplateId() == 0: 49 | farm_factory.addFarmTemplate( 50 | masterchef_template, {"from": accounts[0]}) 51 | 52 | # Create mintable for testing 53 | recipe_02 = MISORecipe02.deploy( 54 | miso_token_factory, 55 | weth_token, 56 | miso_market, 57 | miso_launcher, 58 | uniswap_factory, 59 | farm_factory, 60 | {"from": accounts[0]} 61 | ) 62 | 63 | # recipe_02_address = web3.toChecksumAddress(0x3FD2f53bA85345E17aF41e845f1c41014962db5F) 64 | # recipe_02 = MISORecipe02.at(recipe_02_address) 65 | 66 | # Access control admin must set the smart contract roles 67 | # user_access_control.addSmartContractRole(recipe_02, {'from': accounts[0]}) 68 | 69 | name = "Token" 70 | symbol = "TKN" 71 | tokensToMint = 1000 * TENPOW18 72 | tokensToMarket = 200 * TENPOW18 73 | paymentCurrency = ETH_ADDRESS 74 | 75 | startTime = chain.time() + 50 76 | endTime = chain.time() + 1000 77 | market_rate = 100 78 | market_goal = 200 79 | 80 | launchwindow = 3 * 24 * 60 * 60 81 | deadline = 200 82 | locktime = 100 83 | tokensToLiquidity = 100 * TENPOW18 84 | 85 | # Create new Farm 86 | rewards_per_block = 1 * TENPOW18 87 | # Define the start time relative to sales 88 | start_block = len(chain) + 10 89 | dev_addr = wallet 90 | tokensToFarm = 100 * TENPOW18 91 | alloc_point = 10 92 | integratorFeeAccount = accounts[1] 93 | 94 | tx = recipe_02.prepareMiso( 95 | name, 96 | symbol, 97 | user_access_control, 98 | tokensToMint, 99 | tokensToMarket, 100 | paymentCurrency, 101 | 102 | startTime, 103 | endTime, 104 | market_rate, 105 | market_goal, 106 | wallet, 107 | operator, 108 | 109 | deadline, 110 | launchwindow, 111 | locktime, 112 | tokensToLiquidity, 113 | 114 | rewards_per_block, 115 | start_block, 116 | dev_addr, 117 | tokensToFarm, 118 | alloc_point, 119 | integratorFeeAccount, {'from': accounts[0]} 120 | ) 121 | time.sleep(1) 122 | print("tx events: " + str(tx.events)) 123 | -------------------------------------------------------------------------------- /contracts/OpenZeppelin/token/ERC20/SafeERC20.sol: -------------------------------------------------------------------------------- 1 | 2 | 3 | pragma solidity 0.6.12; 4 | 5 | import "../../../interfaces/IERC20.sol"; 6 | import "../../math/SafeMath.sol"; 7 | import "../../utils/Address.sol"; 8 | 9 | /** 10 | * @title SafeERC20 11 | * @dev Wrappers around ERC20 operations that throw on failure (when the token 12 | * contract returns false). Tokens that return no value (and instead revert or 13 | * throw on failure) are also supported, non-reverting calls are assumed to be 14 | * successful. 15 | * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, 16 | * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. 17 | */ 18 | library SafeERC20 { 19 | using SafeMath for uint256; 20 | using Address for address; 21 | 22 | function safeTransfer(IERC20 token, address to, uint256 value) internal { 23 | // 0xa9059cbb = bytes4(keccak256("transfer(address,uint256)")) 24 | _callOptionalReturn(token, abi.encodeWithSelector(0xa9059cbb, to, value)); 25 | } 26 | 27 | function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { 28 | // 0x23b872dd = bytes4(keccak256("transferFrom(address,address,uint256)")) 29 | _callOptionalReturn(token, abi.encodeWithSelector(0x23b872dd, from, to, value)); 30 | } 31 | 32 | /** 33 | * @dev Deprecated. This function has issues similar to the ones found in 34 | * {IERC20-approve}, and its usage is discouraged. 35 | * 36 | * Whenever possible, use {safeIncreaseAllowance} and 37 | * {safeDecreaseAllowance} instead. 38 | */ 39 | function safeApprove(IERC20 token, address spender, uint256 value) internal { 40 | // safeApprove should only be called when setting an initial allowance, 41 | // or when resetting it to zero. To increase and decrease it, use 42 | // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 43 | // solhint-disable-next-line max-line-length 44 | require((value == 0) || (token.allowance(address(this), spender) == 0), 45 | "SafeERC20: approve from non-zero to non-zero allowance" 46 | ); 47 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 48 | } 49 | 50 | function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { 51 | uint256 newAllowance = token.allowance(address(this), spender).add(value); 52 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 53 | } 54 | 55 | function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { 56 | uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); 57 | _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); 58 | } 59 | 60 | /** 61 | * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement 62 | * on the return value: the return value is optional (but if data is returned, it must not be false). 63 | * @param token The token targeted by the call. 64 | * @param data The call data (encoded using abi.encode or one of its variants). 65 | */ 66 | function _callOptionalReturn(IERC20 token, bytes memory data) private { 67 | // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since 68 | // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that 69 | // the target address contains contract code and also asserts for success in the low-level call. 70 | 71 | bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 72 | if (returndata.length > 0) { // Return data is optional 73 | // solhint-disable-next-line max-line-length 74 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/test_token_lock.py: -------------------------------------------------------------------------------- 1 | from brownie import accounts, web3, Wei, reverts, chain 2 | from brownie.network.transaction import TransactionReceipt 3 | from brownie.convert import to_address 4 | import pytest 5 | from brownie import Contract 6 | from settings import * 7 | 8 | # reset the chain after every test case 9 | @pytest.fixture(autouse=True) 10 | def isolation(fn_isolation): 11 | pass 12 | 13 | @pytest.fixture(scope="function") 14 | def token_locks_active(token_lock,fixed_token2): 15 | 16 | unlockTime = chain.time() + 10 17 | 18 | fixed_token2.transfer(accounts[1], 2* TENPOW18, {"from": accounts[0]}) 19 | balance_before_lock = fixed_token2.balanceOf(accounts[1]) 20 | 21 | fixed_token2.approve(token_lock, 2* TENPOW18,{"from": accounts[1]}) 22 | token_lock.lockTokens(fixed_token2, 23 | 1 * TENPOW18, 24 | unlockTime, 25 | accounts[1], 26 | {"from":accounts[1]}) 27 | balance_after_lock = fixed_token2.balanceOf(accounts[1]) 28 | 29 | assert balance_before_lock - balance_after_lock== 1 * TENPOW18 30 | assert fixed_token2.balanceOf(token_lock) == 1 * TENPOW18 31 | 32 | fixed_token2.transfer(accounts[2], 2* TENPOW18, {"from": accounts[0]}) 33 | balance_before_lock = fixed_token2.balanceOf(accounts[2]) 34 | 35 | fixed_token2.approve(token_lock, 2* TENPOW18,{"from": accounts[2]}) 36 | token_lock.lockTokens(fixed_token2, 37 | 1 * TENPOW18, 38 | unlockTime, 39 | accounts[2], 40 | {"from":accounts[2]}) 41 | balance_after_lock = fixed_token2.balanceOf(accounts[2]) 42 | 43 | assert balance_before_lock - balance_after_lock== 1 * TENPOW18 44 | assert fixed_token2.balanceOf(token_lock) == 2 * TENPOW18 45 | 46 | 47 | 48 | def test_wihdraw(token_locks_active,fixed_token2,token_lock): 49 | 50 | lock_id = 2 51 | amount,unlockTime, owner, userIndex = token_lock.getLockedItemAtId(lock_id) 52 | print(userIndex) 53 | print(amount) 54 | with reverts("LOCK MISMATCH"): 55 | token_lock.withdrawTokens(fixed_token2,userIndex,lock_id,amount, {"from":accounts[1]}) 56 | 57 | 58 | lock_id = 1 59 | amount,unlockTime, owner, userIndex = token_lock.getLockedItemAtId(lock_id) 60 | print(userIndex) 61 | print(unlockTime) 62 | print(amount) 63 | with reverts("Not unlocked yet"): 64 | token_lock.withdrawTokens(fixed_token2,userIndex,lock_id,amount, {"from":accounts[1]}) 65 | 66 | chain.sleep(100) 67 | chain.mine() 68 | lock_id = 1 69 | amount,unlockTime, owner, userIndex = token_lock.getLockedItemAtId(lock_id) 70 | print(userIndex) 71 | 72 | print(amount) 73 | token_lock.withdrawTokens(fixed_token2,userIndex,lock_id,amount, {"from":accounts[1]}) 74 | assert fixed_token2.balanceOf(accounts[1]) == 2 * TENPOW18 75 | assert fixed_token2.balanceOf(token_lock) == 1 * TENPOW18 76 | 77 | 78 | 79 | lock_id = 2 80 | amount,unlockTime, owner, userIndex = token_lock.getLockedItemAtId(lock_id) 81 | print(userIndex) 82 | print(amount) 83 | token_lock.withdrawTokens(fixed_token2,userIndex,lock_id,amount, {"from":accounts[2]}) 84 | assert fixed_token2.balanceOf(accounts[2]) == 2 * TENPOW18 85 | assert fixed_token2.balanceOf(token_lock) == 0 * TENPOW18 86 | amount,unlockTime, owner, userIndex = token_lock.getLockedItemAtId(lock_id) 87 | with reverts("token amount is Zero"): 88 | token_lock.withdrawTokens(fixed_token2,userIndex,lock_id,amount, {"from":accounts[2]}) 89 | 90 | def test_user_locked_item_at_index(token_locks_active,fixed_token2,token_lock): 91 | locked_token = token_lock.getUserLockedItemAtIndex(accounts[1],0) 92 | assert fixed_token2 == locked_token 93 | 94 | def test_item_at_user_index(token_locks_active,fixed_token2,token_lock): 95 | amount, unlockTime, owner, _id = token_lock.getItemAtUserIndex(0,fixed_token2,accounts[1]) 96 | 97 | assert amount == 1 * TENPOW18 98 | #assert unlockTime == chain.time() + 10 99 | assert _id == 1 -------------------------------------------------------------------------------- /contracts/Tokens/MintableToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "../OpenZeppelin/access/AccessControl.sol"; 4 | import "./ERC20/ERC20Burnable.sol"; 5 | import "./ERC20/ERC20Pausable.sol"; 6 | import "../interfaces/IMisoToken.sol"; 7 | 8 | // --------------------------------------------------------------------- 9 | // 10 | // From the MISO Token Factory 11 | // 12 | // Made for Sushi.com 13 | // 14 | // Enjoy. (c) Chef Gonpachi 2021 15 | // 16 | // 17 | // --------------------------------------------------------------------- 18 | // SPDX-License-Identifier: GPL-3.0 19 | // --------------------------------------------------------------------- 20 | 21 | contract MintableToken is AccessControl, ERC20Burnable, ERC20Pausable, IMisoToken { 22 | 23 | /// @notice Miso template id for the token factory. 24 | /// @dev For different token types, this must be incremented. 25 | uint256 public constant override tokenTemplate = 2; 26 | 27 | bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); 28 | bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); 29 | 30 | function initToken(string memory _name, string memory _symbol, address _owner, uint256 _initialSupply) public { 31 | _initERC20(_name, _symbol); 32 | _setupRole(DEFAULT_ADMIN_ROLE, _owner); 33 | _setupRole(MINTER_ROLE, _owner); 34 | _setupRole(PAUSER_ROLE, _owner); 35 | _mint(msg.sender, _initialSupply); 36 | } 37 | 38 | function init(bytes calldata _data) external override payable {} 39 | 40 | function initToken( 41 | bytes calldata _data 42 | ) public override { 43 | (string memory _name, 44 | string memory _symbol, 45 | address _owner, 46 | uint256 _initialSupply) = abi.decode(_data, (string, string, address, uint256)); 47 | 48 | initToken(_name,_symbol,_owner,_initialSupply); 49 | } 50 | 51 | /** 52 | * @dev Generates init data for Token Factory 53 | * @param _name - Token name 54 | * @param _symbol - Token symbol 55 | * @param _owner - Contract owner 56 | * @param _initialSupply Amount of tokens minted on creation 57 | */ 58 | function getInitData( 59 | string calldata _name, 60 | string calldata _symbol, 61 | address _owner, 62 | uint256 _initialSupply 63 | ) 64 | external 65 | pure 66 | returns (bytes memory _data) 67 | { 68 | return abi.encode(_name, _symbol, _owner, _initialSupply); 69 | } 70 | 71 | 72 | 73 | /** 74 | * @dev Creates `amount` new tokens for `to`. 75 | * 76 | * See {ERC20-_mint}. 77 | * 78 | * Requirements: 79 | * 80 | * - the caller must have the `MINTER_ROLE`. 81 | */ 82 | function mint(address to, uint256 amount) public virtual { 83 | require(hasRole(MINTER_ROLE, _msgSender()), "MintableToken: must have minter role to mint"); 84 | _mint(to, amount); 85 | } 86 | 87 | /** 88 | * @dev Pauses all token transfers. 89 | * 90 | * See {ERC20Pausable} and {Pausable-_pause}. 91 | * 92 | * Requirements: 93 | * 94 | * - the caller must have the `PAUSER_ROLE`. 95 | */ 96 | function pause() public virtual { 97 | require(hasRole(PAUSER_ROLE, _msgSender()), "MintableToken: must have pauser role to pause"); 98 | _pause(); 99 | } 100 | 101 | /** 102 | * @dev Unpauses all token transfers. 103 | * 104 | * See {ERC20Pausable} and {Pausable-_unpause}. 105 | * 106 | * Requirements: 107 | * 108 | * - the caller must have the `PAUSER_ROLE`. 109 | */ 110 | function unpause() public virtual { 111 | require(hasRole(PAUSER_ROLE, _msgSender()), "MintableToken: must have pauser role to unpause"); 112 | _unpause(); 113 | } 114 | 115 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override(ERC20, ERC20Pausable) { 116 | super._beforeTokenTransfer(from, to, amount); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /contracts/Utils/Documents.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | pragma experimental ABIEncoderV2; 3 | 4 | 5 | /** 6 | * @title Standard implementation of ERC1643 Document management 7 | */ 8 | contract Documents { 9 | 10 | struct Document { 11 | uint32 docIndex; // Store the document name indexes 12 | uint64 lastModified; // Timestamp at which document details was last modified 13 | string data; // data of the document that exist off-chain 14 | } 15 | 16 | // mapping to store the documents details in the document 17 | mapping(string => Document) internal _documents; 18 | // mapping to store the document name indexes 19 | mapping(string => uint32) internal _docIndexes; 20 | // Array use to store all the document name present in the contracts 21 | string[] _docNames; 22 | 23 | // Document Events 24 | event DocumentRemoved(string indexed _name, string _data); 25 | event DocumentUpdated(string indexed _name, string _data); 26 | 27 | /** 28 | * @notice Used to attach a new document to the contract, or update the data or hash of an existing attached document 29 | * @dev Can only be executed by the owner of the contract. 30 | * @param _name Name of the document. It should be unique always 31 | * @param _data Off-chain data of the document from where it is accessible to investors/advisors to read. 32 | */ 33 | function _setDocument(string calldata _name, string calldata _data) internal { 34 | require(bytes(_name).length > 0, "Zero name is not allowed"); 35 | require(bytes(_data).length > 0, "Should not be a empty data"); 36 | // Document storage document = _documents[_name]; 37 | if (_documents[_name].lastModified == uint64(0)) { 38 | _docNames.push(_name); 39 | _documents[_name].docIndex = uint32(_docNames.length); 40 | } 41 | _documents[_name] = Document(_documents[_name].docIndex, uint64(now), _data); 42 | emit DocumentUpdated(_name, _data); 43 | } 44 | 45 | /** 46 | * @notice Used to remove an existing document from the contract by giving the name of the document. 47 | * @dev Can only be executed by the owner of the contract. 48 | * @param _name Name of the document. It should be unique always 49 | */ 50 | 51 | function _removeDocument(string calldata _name) internal { 52 | require(_documents[_name].lastModified != uint64(0), "Document should exist"); 53 | uint32 index = _documents[_name].docIndex - 1; 54 | if (index != _docNames.length - 1) { 55 | _docNames[index] = _docNames[_docNames.length - 1]; 56 | _documents[_docNames[index]].docIndex = index + 1; 57 | } 58 | _docNames.pop(); 59 | emit DocumentRemoved(_name, _documents[_name].data); 60 | delete _documents[_name]; 61 | } 62 | 63 | /** 64 | * @notice Used to return the details of a document with a known name (`string`). 65 | * @param _name Name of the document 66 | * @return string The data associated with the document. 67 | * @return uint256 the timestamp at which the document was last modified. 68 | */ 69 | function getDocument(string calldata _name) external view returns (string memory, uint256) { 70 | return ( 71 | _documents[_name].data, 72 | uint256(_documents[_name].lastModified) 73 | ); 74 | } 75 | 76 | /** 77 | * @notice Used to retrieve a full list of documents attached to the smart contract. 78 | * @return string List of all documents names present in the contract. 79 | */ 80 | function getAllDocuments() external view returns (string[] memory) { 81 | return _docNames; 82 | } 83 | 84 | /** 85 | * @notice Used to retrieve the total documents in the smart contract. 86 | * @return uint256 Count of the document names present in the contract. 87 | */ 88 | function getDocumentCount() external view returns (uint256) { 89 | return _docNames.length; 90 | } 91 | 92 | /** 93 | * @notice Used to retrieve the document name from index in the smart contract. 94 | * @return string Name of the document name. 95 | */ 96 | function getDocumentName(uint256 _index) external view returns (string memory) { 97 | require(_index < _docNames.length, "Index out of bounds"); 98 | return _docNames[_index]; 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /contracts/UniswapV2/UniswapV2Library.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import './interfaces/IUniswapV2Pair.sol'; 4 | 5 | import "./libraries/SafeMath.sol"; 6 | 7 | library UniswapV2Library { 8 | using SafeMathUniswap for uint; 9 | 10 | // returns sorted token addresses, used to handle return values from pairs sorted in this order 11 | function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { 12 | require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES'); 13 | (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); 14 | require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS'); 15 | } 16 | 17 | // calculates the CREATE2 address for a pair without making any external calls 18 | function pairFor(address factory, address tokenA, address tokenB, bytes32 pairCodeHash) internal pure returns (address pair) { 19 | (address token0, address token1) = sortTokens(tokenA, tokenB); 20 | pair = address(uint(keccak256(abi.encodePacked( 21 | hex'ff', 22 | factory, 23 | keccak256(abi.encodePacked(token0, token1)), 24 | pairCodeHash // init code hash 25 | )))); 26 | } 27 | 28 | // fetches and sorts the reserves for a pair 29 | function getReserves(address factory, address tokenA, address tokenB, bytes32 pairCodeHash) internal view returns (uint reserveA, uint reserveB) { 30 | (address token0,) = sortTokens(tokenA, tokenB); 31 | (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB, pairCodeHash)).getReserves(); 32 | (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); 33 | } 34 | 35 | // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset 36 | function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { 37 | require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT'); 38 | require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); 39 | amountB = amountA.mul(reserveB) / reserveA; 40 | } 41 | 42 | // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset 43 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { 44 | require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT'); 45 | require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); 46 | uint amountInWithFee = amountIn.mul(997); 47 | uint numerator = amountInWithFee.mul(reserveOut); 48 | uint denominator = reserveIn.mul(1000).add(amountInWithFee); 49 | amountOut = numerator / denominator; 50 | } 51 | 52 | // given an output amount of an asset and pair reserves, returns a required input amount of the other asset 53 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { 54 | require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT'); 55 | require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); 56 | uint numerator = reserveIn.mul(amountOut).mul(1000); 57 | uint denominator = reserveOut.sub(amountOut).mul(997); 58 | amountIn = (numerator / denominator).add(1); 59 | } 60 | 61 | // performs chained getAmountOut calculations on any number of pairs 62 | function getAmountsOut(address factory, uint amountIn, address[] memory path, bytes32 pairCodeHash) internal view returns (uint[] memory amounts) { 63 | require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); 64 | amounts = new uint[](path.length); 65 | amounts[0] = amountIn; 66 | for (uint i; i < path.length - 1; i++) { 67 | (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1], pairCodeHash); 68 | amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); 69 | } 70 | } 71 | 72 | // performs chained getAmountIn calculations on any number of pairs 73 | function getAmountsIn(address factory, uint amountOut, address[] memory path, bytes32 pairCodeHash) internal view returns (uint[] memory amounts) { 74 | require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); 75 | amounts = new uint[](path.length); 76 | amounts[amounts.length - 1] = amountOut; 77 | for (uint i = path.length - 1; i > 0; i--) { 78 | (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i], pairCodeHash); 79 | amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /contracts/Vault/GnosisSafeFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "../Access/MISOAccessControls.sol"; 4 | import "../interfaces/IGnosisProxyFactory.sol"; 5 | import "../interfaces/ISafeGnosis.sol"; 6 | import "../interfaces/IERC20.sol"; 7 | 8 | 9 | contract GnosisSafeFactory { 10 | 11 | /// @notice ISafeGnosis interface. 12 | ISafeGnosis public safeGnosis; 13 | 14 | /// @notice IGnosisProxyFactory interface. 15 | IGnosisProxyFactory public proxyFactory; 16 | 17 | /// @notice MISOAccessControls interface. 18 | MISOAccessControls public accessControls; 19 | 20 | /// @notice Whether initialized or not. 21 | bool private initialised; 22 | 23 | /// @notice Mapping from user address to Gnosis Safe interface. 24 | mapping(address => ISafeGnosis) userToProxy; 25 | 26 | /// @notice Emitted when Gnosis Safe is created. 27 | event GnosisSafeCreated(address indexed user, address indexed proxy, address safeGnosis, address proxyFactory); 28 | 29 | /// @notice Emitted when Gnosis Vault is initialized. 30 | event MisoInitGnosisVault(address sender); 31 | 32 | /// @notice Emitted when Gnosis Safe is updated. 33 | event SafeGnosisUpdated(address indexed sender, address oldSafeGnosis, address newSafeGnosis); 34 | 35 | /// @notice Emitted when Proxy Factory is updated. 36 | event ProxyFactoryUpdated(address indexed sender, address oldProxyFactory, address newProxyFactory); 37 | 38 | /** 39 | * @notice Initializes Gnosis Vault with safe, proxy and accesscontrols contracts. 40 | * @param _accessControls AccessControls contract address. 41 | * @param _safeGnosis SafeGnosis contract address. 42 | * @param _proxyFactory ProxyFactory contract address. 43 | */ 44 | function initGnosisVault(address _accessControls, address _safeGnosis, address _proxyFactory) public { 45 | require(!initialised); 46 | safeGnosis = ISafeGnosis(_safeGnosis); 47 | proxyFactory = IGnosisProxyFactory(_proxyFactory); 48 | accessControls = MISOAccessControls(_accessControls); 49 | initialised = true; 50 | emit MisoInitGnosisVault(msg.sender); 51 | } 52 | 53 | /** 54 | * @notice Function that can change Gnosis Safe contract address. 55 | * @param _safeGnosis SafeGnosis contract address. 56 | */ 57 | function setSafeGnosis(address _safeGnosis) external { 58 | require(accessControls.hasOperatorRole(msg.sender), "GnosisVault.setSafeGnosis: Sender must be operator"); 59 | address oldSafeGnosis = address(safeGnosis); 60 | safeGnosis = ISafeGnosis(_safeGnosis); 61 | emit SafeGnosisUpdated(msg.sender, oldSafeGnosis, address(safeGnosis)); 62 | } 63 | 64 | /** 65 | * @notice Function that can change Proxy Factory contract address. 66 | * @param _proxyFactory ProxyFactory contract address. 67 | */ 68 | function setProxyFactory(address _proxyFactory) external { 69 | require(accessControls.hasOperatorRole(msg.sender), "GnosisVault.setProxyFactory: Sender must be operator"); 70 | address oldProxyFactory = address(proxyFactory); 71 | proxyFactory = IGnosisProxyFactory(_proxyFactory); 72 | emit ProxyFactoryUpdated(msg.sender, oldProxyFactory, address(proxyFactory)); 73 | } 74 | 75 | /** 76 | * @notice Function for creating a new safe. 77 | * @param _owners List of Safe owners. 78 | * @param _threshold Number of required confirmations for a Safe transaction. 79 | * @param to Contract address for optional delegate call. 80 | * @param data Data payload for optional delegate call. 81 | * @param fallbackHandler Handler for fallback calls to this contract. 82 | * @param paymentToken Token that should be used for the payment (0 is ETH). 83 | * @param payment Value that should be paid. 84 | * @param paymentReceiver Address that should receive the payment (or 0 if tx.origin). 85 | */ 86 | function createSafe( 87 | address[] calldata _owners, 88 | uint256 _threshold, 89 | address to, 90 | bytes calldata data, 91 | address fallbackHandler, 92 | address paymentToken, 93 | uint256 payment, 94 | address payable paymentReceiver 95 | ) 96 | public returns (ISafeGnosis proxy) 97 | { 98 | bytes memory safeGnosisData = abi.encode("setup(address[],uint256,address,bytes,address,address,uint256,address)", 99 | _owners,_threshold,to,data,fallbackHandler,paymentToken,payment,paymentReceiver); 100 | proxy = proxyFactory.createProxy( 101 | safeGnosis, 102 | safeGnosisData 103 | ); 104 | userToProxy[msg.sender] = proxy; 105 | emit GnosisSafeCreated(msg.sender, address(proxy), address(safeGnosis), address(proxyFactory)); 106 | return proxy; 107 | } 108 | /// GP: Can we also use the proxy with a nonce? Incase we need it. 109 | /// GP: Can we have a simplifed version with a few things already set? eg an ETH by default verision. 110 | /// GP: Can we set empty data or preset the feedback handler? Whats the minimum feilds required? 111 | } 112 | -------------------------------------------------------------------------------- /contracts/Access/MISOAccessFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "../Utils/CloneFactory.sol"; 4 | import "./MISOAccessControls.sol"; 5 | 6 | 7 | contract MISOAccessFactory is CloneFactory { 8 | 9 | /// @notice Responsible for access rights to the contract. 10 | MISOAccessControls public accessControls; 11 | 12 | /// @notice Address of the template for access controls. 13 | address public accessControlTemplate; 14 | 15 | /// @notice Whether initialized or not. 16 | bool private initialised; 17 | 18 | /// @notice Minimum fee number. 19 | uint256 public minimumFee; 20 | 21 | /// @notice Devs address. 22 | address public devaddr; 23 | 24 | /// @notice AccessControls created using the factory. 25 | address[] public children; 26 | 27 | /// @notice Tracks if a contract is made by the factory. 28 | mapping(address => bool) public isChild; 29 | 30 | /// @notice Event emitted when first initializing Miso AccessControl Factory. 31 | event MisoInitAccessFactory(address sender); 32 | 33 | /// @notice Event emitted when a access is created using template id. 34 | event AccessControlCreated(address indexed owner, address accessControls, address admin, address accessTemplate); 35 | 36 | /// @notice Event emitted when a access template is added. 37 | event AccessControlTemplateAdded(address oldAccessControl, address newAccessControl); 38 | 39 | /// @notice Event emitted when a access template is removed. 40 | event AccessControlTemplateRemoved(address access, uint256 templateId); 41 | 42 | /// @notice Event emitted when a access template is removed. 43 | event MinimumFeeUpdated(uint oldFee, uint newFee); 44 | 45 | /// @notice Event emitted when a access template is removed. 46 | event DevAddressUpdated(address oldDev, address newDev); 47 | 48 | 49 | constructor() public { 50 | } 51 | 52 | /** 53 | * @notice Single gateway to initialize the MISO AccessControl Factory with proper address and set minimum fee. 54 | * @dev Can only be initialized once. 55 | * @param _minimumFee Minimum fee number. 56 | * @param _accessControls Address of the access controls. 57 | */ 58 | function initMISOAccessFactory(uint256 _minimumFee, address _accessControls) external { 59 | require(!initialised); 60 | initialised = true; 61 | minimumFee = _minimumFee; 62 | accessControls = MISOAccessControls(_accessControls); 63 | emit MisoInitAccessFactory(msg.sender); 64 | } 65 | 66 | /// @notice Get the total number of children in the factory. 67 | function numberOfChildren() external view returns (uint256) { 68 | return children.length; 69 | } 70 | 71 | /** 72 | * @notice Creates access corresponding to template id. 73 | * @dev Initializes access with parameters passed. 74 | * @param _admin Address of admin access. 75 | */ 76 | function deployAccessControl(address _admin) external payable returns (address access) { 77 | require(msg.value >= minimumFee); 78 | require(accessControlTemplate != address(0)); 79 | access = createClone(accessControlTemplate); 80 | isChild[address(access)] = true; 81 | children.push(address(access)); 82 | MISOAccessControls(access).initAccessControls(_admin); 83 | emit AccessControlCreated(msg.sender, address(access), _admin, accessControlTemplate); 84 | if (msg.value > 0) { 85 | payable(devaddr).transfer(msg.value); 86 | } 87 | } 88 | 89 | /** 90 | * @notice Function to add new contract templates for the factory. 91 | * @dev Should have operator access. 92 | * @param _template Template to create new access controls. 93 | */ 94 | function updateAccessTemplate(address _template) external { 95 | require( 96 | accessControls.hasAdminRole(msg.sender), 97 | "MISOAccessFactory.updateAccessTemplate: Sender must be admin" 98 | ); 99 | require(_template != address(0)); 100 | emit AccessControlTemplateAdded(_template, accessControlTemplate); 101 | accessControlTemplate = _template; 102 | } 103 | 104 | /** 105 | * @notice Sets dev address. 106 | * @dev Should have operator access. 107 | * @param _devaddr Devs address. 108 | */ 109 | function setDev(address _devaddr) external { 110 | require( 111 | accessControls.hasAdminRole(msg.sender), 112 | "MISOAccessFactory.setMinimumFee: Sender must be admin" 113 | ); 114 | emit DevAddressUpdated(devaddr, _devaddr); 115 | devaddr = _devaddr; 116 | } 117 | 118 | /** 119 | * @notice Sets minimum fee. 120 | * @dev Should have operator access. 121 | * @param _minimumFee Minimum fee number. 122 | */ 123 | function setMinimumFee(uint256 _minimumFee) external { 124 | require( 125 | accessControls.hasAdminRole(msg.sender), 126 | "MISOAccessFactory.setMinimumFee: Sender must be admin" 127 | ); 128 | emit MinimumFeeUpdated(minimumFee, _minimumFee); 129 | minimumFee = _minimumFee; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /contracts/Access/MISOAccessControls.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "./MISOAdminAccess.sol"; 4 | 5 | /** 6 | * @notice Access Controls 7 | * @author Attr: BlockRocket.tech 8 | */ 9 | contract MISOAccessControls is MISOAdminAccess { 10 | /// @notice Role definitions 11 | bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); 12 | bytes32 public constant SMART_CONTRACT_ROLE = keccak256("SMART_CONTRACT_ROLE"); 13 | bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE"); 14 | 15 | /// @notice Events for adding and removing various roles 16 | 17 | event MinterRoleGranted( 18 | address indexed beneficiary, 19 | address indexed caller 20 | ); 21 | 22 | event MinterRoleRemoved( 23 | address indexed beneficiary, 24 | address indexed caller 25 | ); 26 | 27 | event OperatorRoleGranted( 28 | address indexed beneficiary, 29 | address indexed caller 30 | ); 31 | 32 | event OperatorRoleRemoved( 33 | address indexed beneficiary, 34 | address indexed caller 35 | ); 36 | 37 | event SmartContractRoleGranted( 38 | address indexed beneficiary, 39 | address indexed caller 40 | ); 41 | 42 | event SmartContractRoleRemoved( 43 | address indexed beneficiary, 44 | address indexed caller 45 | ); 46 | 47 | /** 48 | * @notice The deployer is automatically given the admin role which will allow them to then grant roles to other addresses 49 | */ 50 | constructor() public { 51 | } 52 | 53 | 54 | ///////////// 55 | // Lookups // 56 | ///////////// 57 | 58 | /** 59 | * @notice Used to check whether an address has the minter role 60 | * @param _address EOA or contract being checked 61 | * @return bool True if the account has the role or false if it does not 62 | */ 63 | function hasMinterRole(address _address) public view returns (bool) { 64 | return hasRole(MINTER_ROLE, _address); 65 | } 66 | 67 | /** 68 | * @notice Used to check whether an address has the smart contract role 69 | * @param _address EOA or contract being checked 70 | * @return bool True if the account has the role or false if it does not 71 | */ 72 | function hasSmartContractRole(address _address) public view returns (bool) { 73 | return hasRole(SMART_CONTRACT_ROLE, _address); 74 | } 75 | 76 | /** 77 | * @notice Used to check whether an address has the operator role 78 | * @param _address EOA or contract being checked 79 | * @return bool True if the account has the role or false if it does not 80 | */ 81 | function hasOperatorRole(address _address) public view returns (bool) { 82 | return hasRole(OPERATOR_ROLE, _address); 83 | } 84 | 85 | /////////////// 86 | // Modifiers // 87 | /////////////// 88 | 89 | /** 90 | * @notice Grants the minter role to an address 91 | * @dev The sender must have the admin role 92 | * @param _address EOA or contract receiving the new role 93 | */ 94 | function addMinterRole(address _address) external { 95 | grantRole(MINTER_ROLE, _address); 96 | emit MinterRoleGranted(_address, _msgSender()); 97 | } 98 | 99 | /** 100 | * @notice Removes the minter role from an address 101 | * @dev The sender must have the admin role 102 | * @param _address EOA or contract affected 103 | */ 104 | function removeMinterRole(address _address) external { 105 | revokeRole(MINTER_ROLE, _address); 106 | emit MinterRoleRemoved(_address, _msgSender()); 107 | } 108 | 109 | /** 110 | * @notice Grants the smart contract role to an address 111 | * @dev The sender must have the admin role 112 | * @param _address EOA or contract receiving the new role 113 | */ 114 | function addSmartContractRole(address _address) external { 115 | grantRole(SMART_CONTRACT_ROLE, _address); 116 | emit SmartContractRoleGranted(_address, _msgSender()); 117 | } 118 | 119 | /** 120 | * @notice Removes the smart contract role from an address 121 | * @dev The sender must have the admin role 122 | * @param _address EOA or contract affected 123 | */ 124 | function removeSmartContractRole(address _address) external { 125 | revokeRole(SMART_CONTRACT_ROLE, _address); 126 | emit SmartContractRoleRemoved(_address, _msgSender()); 127 | } 128 | 129 | /** 130 | * @notice Grants the operator role to an address 131 | * @dev The sender must have the admin role 132 | * @param _address EOA or contract receiving the new role 133 | */ 134 | function addOperatorRole(address _address) external { 135 | grantRole(OPERATOR_ROLE, _address); 136 | emit OperatorRoleGranted(_address, _msgSender()); 137 | } 138 | 139 | /** 140 | * @notice Removes the operator role from an address 141 | * @dev The sender must have the admin role 142 | * @param _address EOA or contract affected 143 | */ 144 | function removeOperatorRole(address _address) external { 145 | revokeRole(OPERATOR_ROLE, _address); 146 | emit OperatorRoleRemoved(_address, _msgSender()); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /contracts/Recipes/MISORecipe03.vy: -------------------------------------------------------------------------------- 1 | # @version 0.2.8 2 | 3 | # 4 | """ 5 | @title MVP for preparing a MISO set menu 6 | @author chefgonpachi 7 | @notice Use this contract to create a liquidity farm from exisiting tokens 8 | """ 9 | 10 | from vyper.interfaces import ERC20 11 | 12 | interface IMISOFarmFactory: 13 | def createFarm( 14 | rewards: address, 15 | rewardsPerBlock: uint256, 16 | startBlock: uint256, 17 | devaddr: address, 18 | accessControls: address, 19 | templateId: uint256 20 | ) -> address: payable 21 | def deployFarm( 22 | templateId: uint256, 23 | integratorFeeAccount: address 24 | ) -> address: payable 25 | 26 | interface IMasterChef: 27 | def initFarm( 28 | rewards: address, 29 | rewardsPerBlock: uint256, 30 | startBlock: uint256, 31 | devaddr: address, 32 | accessControls: address 33 | ) : nonpayable 34 | def addToken(allocPoint: uint256, lpToken: address, withUpdate: bool) : nonpayable 35 | 36 | interface ISushiToken: 37 | def mint(owner: address, amount: uint256) : nonpayable 38 | def approve(spender: address, amount: uint256) -> bool: nonpayable 39 | def transfer(to: address, amount: uint256) -> bool: nonpayable 40 | 41 | interface Factory: 42 | def getPair(tokenA: address, tokenB: address) -> address: view 43 | def createPair(tokenA: address, tokenB: address) -> address: nonpayable 44 | 45 | interface IMISOAccess: 46 | def hasAdminRole(addr: address) -> bool: view 47 | def addAdminRole(addr: address) : nonpayable 48 | def removeAdminRole(addr: address) : nonpayable 49 | 50 | 51 | weth: public(address) 52 | farmFactory: public(IMISOFarmFactory) 53 | sushiswapFactory: public(address) 54 | 55 | 56 | @external 57 | def __init__( 58 | weth: address, 59 | sushiswapFactory: address, 60 | farmFactory: address 61 | ): 62 | """ 63 | @notice Recipe Number 03 - Takes an existing token and creates a liquidity farm 64 | @param weth - Wrapped Ethers contract address 65 | @param sushiswapFactory - The SushiSwap factory to create new pools 66 | @param farmFactory - A factory that makes farms that can stake and reward your new tokens 67 | """ 68 | 69 | self.weth = weth 70 | self.sushiswapFactory = sushiswapFactory 71 | self.farmFactory = IMISOFarmFactory(farmFactory) 72 | 73 | @payable 74 | @external 75 | def createLiquidityFarm( 76 | 77 | rewardToken: address, 78 | tokensToFarm: uint256, 79 | rewardsPerBlock: uint256, 80 | startBlock: uint256, 81 | devAddr: address, 82 | allocPoint: uint256, 83 | admin: address 84 | 85 | ) -> (address): 86 | """ 87 | @notice Creates a farm for rewarding liquidity with WETH backed SLP tokens 88 | @param rewardToken - Rewards token address 89 | @param rewardsPerBlock - Rewards per block for the whole farm 90 | @param startBlock - Starting block 91 | @param devAddr - Any donations if set are sent here 92 | @param tokensToFarm - Total amount of tokens to be sent to the farm as rewards 93 | @param allocPoint - Initial weighting of the lp token. Set relative to additional pools 94 | """ 95 | 96 | assert (block.number < startBlock) # dev: Start time later then end time 97 | assert ERC20(rewardToken).transferFrom(msg.sender, self, tokensToFarm) 98 | 99 | pair: address = Factory(self.sushiswapFactory).getPair(rewardToken, self.weth) 100 | if pair == ZERO_ADDRESS: 101 | pair = Factory(self.sushiswapFactory).createPair(rewardToken, self.weth) 102 | 103 | farm: address = self.farmFactory.deployFarm(1, msg.sender) 104 | 105 | IMasterChef(farm).initFarm( 106 | rewardToken, 107 | rewardsPerBlock, 108 | startBlock, 109 | devAddr, 110 | self) 111 | 112 | 113 | ISushiToken(rewardToken).transfer(farm,tokensToFarm) 114 | IMasterChef(farm).addToken(allocPoint, pair, False) 115 | IMISOAccess(farm).addAdminRole(admin) 116 | assert IMISOAccess(farm).hasAdminRole(admin) == True 117 | IMISOAccess(farm).removeAdminRole(self) 118 | 119 | return (farm) 120 | 121 | 122 | 123 | 124 | @external 125 | def createTokenFarm( 126 | 127 | rewardToken: address, 128 | tokensToFarm: uint256, 129 | rewardsPerBlock: uint256, 130 | startBlock: uint256, 131 | devAddr: address, 132 | 133 | stakedToken: address, 134 | allocPoint: uint256, 135 | 136 | # to create in recipe 137 | accessControl: address 138 | 139 | ) -> (address): 140 | """ 141 | @notice Creates a farm for rewarding tokens for staking a different token 142 | @param rewardToken - Rewards token address 143 | @param rewardsPerBlock - Rewards per block for the whole farm 144 | @param startBlock - Starting block 145 | @param devAddr - Any donations if set are sent here 146 | @param tokensToFarm - Total amount of tokens to be sent to the farm as rewards 147 | @param allocPoint - Initial weighting of the lp token. Set relative to additional pools 148 | """ 149 | 150 | assert (block.number < startBlock) # dev: Start time later then end time 151 | assert ERC20(rewardToken).transferFrom(msg.sender, self, tokensToFarm) 152 | 153 | # create access control 154 | # transfer ownership to msg.sender 155 | farm: address = self.farmFactory.deployFarm(1, msg.sender) 156 | 157 | IMasterChef(farm).initFarm( 158 | rewardToken, 159 | rewardsPerBlock, 160 | startBlock, 161 | devAddr, 162 | self) 163 | 164 | ISushiToken(rewardToken).transfer(farm,tokensToFarm) 165 | # IMasterChef(farm).addToken(allocPoint, stakedToken, False) 166 | 167 | return (farm) 168 | 169 | -------------------------------------------------------------------------------- /scripts/deploy_MISO_dev.py: -------------------------------------------------------------------------------- 1 | from brownie import * 2 | from .settings import * 3 | from .contracts import * 4 | from .contract_addresses import * 5 | import time 6 | 7 | 8 | def main(): 9 | load_accounts() 10 | 11 | # Initialise Project 12 | operator = accounts[0] 13 | owner = accounts[0] 14 | wallet = accounts[1] 15 | 16 | # GP: Split into public and miso access control 17 | access_control = deploy_access_control(operator) 18 | 19 | # Setup MISOTokenFactory 20 | miso_token_factory = deploy_miso_token_factory(access_control) 21 | mintable_token_template = deploy_mintable_token_template() 22 | if miso_token_factory.tokenTemplateId() == 0: 23 | miso_token_factory.addTokenTemplate( 24 | mintable_token_template, {'from': operator}) 25 | 26 | # Setup MISO Market 27 | bento_box = deploy_bento_box() 28 | 29 | crowdsale_template = deploy_crowdsale_template() 30 | dutch_auction_template = deploy_dutch_auction_template() 31 | miso_market = deploy_miso_market( 32 | access_control, [dutch_auction_template, crowdsale_template]) 33 | uniswap_factory = deploy_uniswap_factory() 34 | 35 | # MISOLauncher 36 | weth_token = deploy_weth_token() 37 | 38 | pool_liquidity_template = deploy_pool_liquidity_template() 39 | miso_launcher = deploy_miso_launcher(access_control, weth_token, bento_box) 40 | if miso_launcher.getLiquidityTemplateIndex(0) == ZERO_ADDRESS: 41 | miso_launcher.addLiquidityLauncherTemplate( 42 | pool_liquidity_template, {"from": accounts[0]}) 43 | 44 | # MISOFarmFactory 45 | masterchef_template = deploy_masterchef_template() 46 | farm_factory = deploy_farm_factory(access_control) 47 | if farm_factory.farmTemplateId() == 0: 48 | farm_factory.addFarmTemplate( 49 | masterchef_template, {"from": accounts[0]}) 50 | 51 | # ########## 52 | # Testing 53 | # ########## 54 | 55 | # Create mintable for testing 56 | wallet = accounts[1] 57 | templateId = 1 58 | tokens_to_mint = 1000 * TENPOW18 59 | tx = miso_token_factory.createToken( 60 | "Token", "TKN", templateId, owner, tokens_to_mint, {'from': operator}) 61 | rewards_token = MintableToken.at( 62 | web3.toChecksumAddress(tx.events['TokenCreated']['addr'])) 63 | print("rewards_token: " + str(rewards_token)) 64 | 65 | rewards_token.mint(operator, 1000 * TENPOW18, {'from': operator}) 66 | 67 | # Create new Crowdsale Contract 68 | market_tokens = 200 * TENPOW18 69 | market_rate = 100 70 | market_goal = 200 71 | payment_currency = ETH_ADDRESS 72 | 73 | rewards_token.approve(miso_market, market_tokens, {'from': operator}) 74 | tx = miso_market.createCrowdsale( 75 | rewards_token, 76 | market_tokens, 77 | payment_currency, 78 | chain.time() + 50, 79 | chain.time() + 1000, 80 | market_rate, 81 | market_goal, 82 | wallet, 2, 83 | {'from': operator} 84 | ) 85 | 86 | crowdsale = Crowdsale.at(web3.toChecksumAddress( 87 | tx.events['AuctionCreated']['addr'])) 88 | print("crowdsale: " + str(crowdsale)) 89 | 90 | # Create new LiquidityLauncher 91 | # just random numbers atm 92 | launchwindow = 3 * 24 * 60 * 60 93 | deadline = 200 94 | locktime = 100 95 | tx = miso_launcher.deployLauncher(1, operator, {'from': operator}) 96 | pool_liquidity = PoolLiquidity.at(web3.toChecksumAddress( 97 | tx.events['LauncherCreated']['addr'])) 98 | print("pool_liquidity: " + str(pool_liquidity)) 99 | 100 | pool_liquidity.initPoolLiquidity(access_control, 101 | rewards_token, 102 | weth_token, 103 | uniswap_factory, 104 | operator, 105 | wallet, 106 | deadline, 107 | launchwindow, 108 | locktime, {'from': operator}) 109 | 110 | lp_token_address = pool_liquidity.getLPTokenAddress() 111 | lp_token = interface.IERC20(web3.toChecksumAddress(lp_token_address)) 112 | 113 | print("lp_token: " + str(lp_token)) 114 | 115 | rewards_token.transfer(pool_liquidity, 100 * TENPOW18, {'from': operator}) 116 | 117 | # Create new Farm 118 | rewards_per_block = 1 * TENPOW18 119 | # Define the start time relative to sales 120 | start_block = len(chain) + 10 121 | dev_addr = wallet 122 | 123 | tx = farm_factory.createFarm(rewards_token, rewards_per_block, 124 | start_block, dev_addr, access_control, 1, {'from': operator}) 125 | masterchef = MISOMasterChef.at( 126 | web3.toChecksumAddress(tx.events['FarmCreated']['addr'])) 127 | print("masterchef: " + str(masterchef)) 128 | 129 | rewards_token.transfer(masterchef, 100 * TENPOW18, {'from': operator}) 130 | alloc_point = 10 131 | masterchef.addToken(alloc_point, lp_token, False, {'from': operator}) 132 | 133 | if network.show_active() == "development": 134 | # Things to check 135 | # Buy tokens from Crowdsale 136 | # Claim tokens 137 | # Finalise Auction 138 | 139 | # Mock funds from crowdsale to launcher (instead of finalising auction, we just send some eth) 140 | pool_liquidity.depositETH({'from': operator, 'value': 2 * TENPOW18}) 141 | 142 | sleep = pool_liquidity.deadline() - chain.time() + 1 143 | chain.sleep(sleep) 144 | tx = pool_liquidity.launchLiquidityPool({'from': operator}) 145 | liquidity = tx.events['LiquidityAdded']['liquidity'] 146 | print("liquidity: " + str(liquidity)) 147 | 148 | chain.sleep(1) 149 | -------------------------------------------------------------------------------- /contracts/Vault/TokenVault.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.12; 2 | 3 | import "../interfaces/IERC20.sol"; 4 | import "../Utils/SafeMathPlus.sol"; 5 | import "../Utils/SafeTransfer.sol"; 6 | import "../OpenZeppelin/math/SafeMath.sol"; 7 | import "../OpenZeppelin/utils/EnumerableSet.sol"; 8 | 9 | 10 | contract TokenVault is SafeTransfer { 11 | using SafeMath for uint256; 12 | using EnumerableSet for EnumerableSet.AddressSet; 13 | 14 | /// @notice Struct representing each batch of tokens locked in the vault. 15 | struct Item { 16 | uint256 amount; 17 | uint256 unlockTime; 18 | address owner; 19 | uint256 userIndex; 20 | } 21 | 22 | /// @notice Struct that keeps track of assets belonging to a particular user. 23 | struct UserInfo { 24 | mapping(address => uint256[]) lockToItems; 25 | EnumerableSet.AddressSet lockedItemsWithUser; 26 | } 27 | 28 | /// @notice Mapping from user address to UserInfo struct. 29 | mapping (address => UserInfo) users; 30 | 31 | /// @notice Id number of the vault deposit. 32 | uint256 public depositId; 33 | 34 | /// @notice An array of all the deposit Ids. 35 | uint256[] public allDepositIds; 36 | 37 | /// @notice Mapping from item Id to the Item struct. 38 | mapping (uint256 => Item) public lockedItem; 39 | 40 | /// @notice Emitted when tokens are locked inside the vault. 41 | event onLock(address tokenAddress, address user, uint256 amount); 42 | 43 | /// @notice Emitted when tokens are unlocked from the vault. 44 | event onUnlock(address tokenAddress,uint256 amount); 45 | 46 | /** 47 | * @notice Function for locking tokens in the vault. 48 | * @param _tokenAddress Address of the token locked. 49 | * @param _amount Number of tokens locked. 50 | * @param _unlockTime Timestamp number marking when tokens get unlocked. 51 | * @param _withdrawer Address where tokens can be withdrawn after unlocking. 52 | */ 53 | function lockTokens( 54 | address _tokenAddress, 55 | uint256 _amount, 56 | uint256 _unlockTime, 57 | address payable _withdrawer 58 | ) 59 | public returns (uint256 _id) 60 | { 61 | require(_amount > 0, 'token amount is Zero'); 62 | require(_unlockTime < 10000000000, 'Enter an unix timestamp in seconds, not miliseconds'); 63 | _safeTransferFrom(_tokenAddress, msg.sender, _amount); 64 | 65 | _id = ++depositId; 66 | 67 | lockedItem[_id].amount = _amount; 68 | lockedItem[_id].unlockTime = _unlockTime; 69 | lockedItem[_id].owner = _withdrawer; 70 | 71 | allDepositIds.push(_id); 72 | 73 | UserInfo storage userItem = users[_withdrawer]; 74 | userItem.lockedItemsWithUser.add(_tokenAddress); 75 | userItem.lockToItems[_tokenAddress].push(_id); 76 | uint256 userIndex = userItem.lockToItems[_tokenAddress].length - 1; 77 | lockedItem[_id].userIndex = userIndex; 78 | 79 | emit onLock(_tokenAddress, msg.sender,lockedItem[_id].amount); 80 | } 81 | 82 | /** 83 | * @notice Function for withdrawing tokens from the vault. 84 | * @param _tokenAddress Address of the token to withdraw. 85 | * @param _index Index number of the list with Ids. 86 | * @param _id Id number. 87 | * @param _amount Number of tokens to withdraw. 88 | */ 89 | function withdrawTokens( 90 | address _tokenAddress, 91 | uint256 _index, 92 | uint256 _id, 93 | uint256 _amount 94 | ) 95 | external 96 | { 97 | require(_amount > 0, 'token amount is Zero'); 98 | uint256 id = users[msg.sender].lockToItems[_tokenAddress][_index]; 99 | Item storage userItem = lockedItem[id]; 100 | require(id == _id && userItem.owner == msg.sender, 'LOCK MISMATCH'); 101 | require(userItem.unlockTime < block.timestamp, 'Not unlocked yet'); 102 | userItem.amount = userItem.amount.sub(_amount); 103 | 104 | if(userItem.amount == 0) { 105 | uint256[] storage userItems = users[msg.sender].lockToItems[_tokenAddress]; 106 | userItems[_index] = userItems[userItems.length -1]; 107 | userItems.pop(); 108 | } 109 | 110 | _safeTransfer(_tokenAddress, msg.sender, _amount); 111 | 112 | emit onUnlock(_tokenAddress, _amount); 113 | } 114 | 115 | /** 116 | * @notice Function to retrieve data from the Item under user index number. 117 | * @param _index Index number of the list with Item ids. 118 | * @param _tokenAddress Address of the token corresponding to this Item. 119 | * @param _user User address. 120 | * @return Items token amount number, Items unlock timestamp, Items owner address, Items Id number 121 | */ 122 | function getItemAtUserIndex( 123 | uint256 _index, 124 | address _tokenAddress, 125 | address _user 126 | ) 127 | external view returns (uint256, uint256, address, uint256) 128 | { 129 | uint256 id = users[_user].lockToItems[_tokenAddress][_index]; 130 | Item storage item = lockedItem[id]; 131 | return (item.amount, item.unlockTime, item.owner, id); 132 | } 133 | 134 | /** 135 | * @notice Function to retrieve token address at desired index for the specified user. 136 | * @param _user User address. 137 | * @param _index Index number. 138 | * @return Token address. 139 | */ 140 | function getUserLockedItemAtIndex(address _user, uint256 _index) external view returns (address) { 141 | UserInfo storage user = users[_user]; 142 | return user.lockedItemsWithUser.at(_index); 143 | } 144 | 145 | /** 146 | * @notice Function to retrieve all the data from Item struct under given Id. 147 | * @param _id Id number. 148 | * @return All the data for this Id (token amount number, unlock time number, owner address and user index number) 149 | */ 150 | function getLockedItemAtId(uint256 _id) external view returns (uint256, uint256, address, uint256) { 151 | Item storage item = lockedItem[_id]; 152 | return (item.amount, item.unlockTime, item.owner, item.userIndex); 153 | } 154 | } 155 | --------------------------------------------------------------------------------