├── .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 |
--------------------------------------------------------------------------------