├── .browserslistrc
├── public
├── _redirects
├── robots.txt
├── favicon.ico
├── img
│ └── icons
│ │ ├── favicon.ico
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── mstile-150x150.png
│ │ ├── apple-touch-icon.png
│ │ ├── android-chrome-144x144.png
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── apple-touch-icon-60x60.png
│ │ ├── apple-touch-icon-76x76.png
│ │ ├── apple-touch-icon-120x120.png
│ │ ├── apple-touch-icon-152x152.png
│ │ ├── apple-touch-icon-180x180.png
│ │ ├── msapplication-icon-144x144.png
│ │ ├── android-chrome-maskable-192x192.png
│ │ ├── android-chrome-maskable-512x512.png
│ │ ├── browserconfig.xml
│ │ ├── site.webmanifest
│ │ └── safari-pinned-tab.svg
├── index.html
└── service-worker.js
├── .gitattributes
├── src
├── shims-vue-tabs.d.ts
├── assets
│ ├── logo.png
│ ├── smiling-face-with-horns.png
│ └── logo.svg
├── shims-vue.d.ts
├── components
│ ├── Web3Signin.vue
│ └── MinionItem.vue
├── plugins
│ └── vuetify.ts
├── shims-tsx.d.ts
├── views
│ ├── About.vue
│ ├── Home.vue
│ ├── Ens.vue
│ └── NewMinion.vue
├── router
│ └── index.ts
├── main.ts
├── abi
│ ├── moloch_v2_guildbank.json
│ ├── minion.json
│ ├── erc721.json
│ ├── erc20.json
│ ├── moloch_v1_pool.json
│ ├── certnft.json
│ ├── minion_subdomain_registrar.json
│ ├── moloch_v1.json
│ ├── ens_registrar.json
│ └── uniswap_v2_router.json
├── registerServiceWorker.ts
└── App.vue
├── .env-sample
├── cypress.json
├── babel.config.js
├── tests
├── e2e
│ ├── .eslintrc.js
│ ├── specs
│ │ └── example.spec.js
│ ├── support
│ │ ├── index.js
│ │ └── commands.js
│ └── plugins
│ │ └── index.js
├── unit
│ └── example.spec.ts
└── contracts
│ ├── utils
│ ├── types.ts
│ ├── constants.ts
│ └── utils.ts
│ └── minion_integration.spec.ts
├── .vscode
├── extensions.json
└── settings.json
├── vue.config.js
├── networks.js
├── CONTRIBUTORS.md
├── .gitignore
├── README.md
├── contracts
├── mock
│ ├── RevertingMoloch.sol
│ ├── TargetMock.sol
│ └── Token.sol
├── moloch
│ ├── oz
│ │ ├── IERC20.sol
│ │ ├── SafeMath.sol
│ │ ├── LICENSE
│ │ ├── ReentrancyGuard.sol
│ │ └── ERC20.sol
│ ├── tokens
│ │ ├── Token.sol
│ │ └── ClaimsToken.sol
│ ├── MolochSummoner.sol
│ └── test-helpers
│ │ └── Submitter.sol
└── Minion.sol
├── buidler.config.ts
├── .eslintrc.js
├── tsconfig.json
└── package.json
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/public/_redirects:
--------------------------------------------------------------------------------
1 | /* /index.html 200
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sol linguist-language=Solidity
2 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/src/shims-vue-tabs.d.ts:
--------------------------------------------------------------------------------
1 | declare module "vue-nav-tabs";
2 |
--------------------------------------------------------------------------------
/.env-sample:
--------------------------------------------------------------------------------
1 | VUE_APP_CHAIN_ID="42"
2 | VUE_APP_CHAIN="kovan"
3 | VUE_APP_INFURA=
--------------------------------------------------------------------------------
/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "pluginsFile": "tests/e2e/plugins/index.js"
3 | }
4 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["@vue/cli-plugin-babel/preset"]
3 | };
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module "*.vue" {
2 | import Vue from "vue";
3 | export default Vue;
4 | }
5 |
--------------------------------------------------------------------------------
/public/img/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/favicon.ico
--------------------------------------------------------------------------------
/public/img/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/public/img/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/public/img/icons/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/mstile-150x150.png
--------------------------------------------------------------------------------
/public/img/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/src/assets/smiling-face-with-horns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/src/assets/smiling-face-with-horns.png
--------------------------------------------------------------------------------
/public/img/icons/android-chrome-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/android-chrome-144x144.png
--------------------------------------------------------------------------------
/public/img/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/img/icons/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/android-chrome-512x512.png
--------------------------------------------------------------------------------
/public/img/icons/apple-touch-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/apple-touch-icon-60x60.png
--------------------------------------------------------------------------------
/public/img/icons/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/public/img/icons/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/public/img/icons/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/public/img/icons/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/public/img/icons/msapplication-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/msapplication-icon-144x144.png
--------------------------------------------------------------------------------
/public/img/icons/android-chrome-maskable-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/android-chrome-maskable-192x192.png
--------------------------------------------------------------------------------
/public/img/icons/android-chrome-maskable-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raid-guild/moloch-minion/HEAD/public/img/icons/android-chrome-maskable-512x512.png
--------------------------------------------------------------------------------
/tests/e2e/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ["cypress"],
3 | env: {
4 | mocha: true,
5 | "cypress/globals": true
6 | },
7 | rules: {
8 | strict: "off"
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "dbaeumer.vscode-eslint",
4 | "esbenp.prettier-vscode",
5 | "juanblanco.solidity",
6 | "ms-vscode.vscode-typescript-tslint-plugin"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | transpileDependencies: ["vuetify"],
3 | pwa: {
4 | workboxPluginMode: "InjectManifest",
5 | workboxOptions: {
6 | swSrc: "service-worker.js"
7 | }
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/Web3Signin.vue:
--------------------------------------------------------------------------------
1 |
2 | Sign IN
3 |
4 |
11 |
--------------------------------------------------------------------------------
/networks.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | networks: {
3 | development: {
4 | protocol: "http",
5 | host: "localhost",
6 | port: 8545,
7 | gas: 5000000,
8 | gasPrice: 5e9,
9 | networkId: "*"
10 | }
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/src/plugins/vuetify.ts:
--------------------------------------------------------------------------------
1 | import "@fortawesome/fontawesome-free/css/all.css";
2 | import Vue from "vue";
3 | import Vuetify from "vuetify/lib";
4 |
5 | Vue.use(Vuetify);
6 |
7 | export default new Vuetify({
8 | icons: {
9 | iconfont: "fa"
10 | }
11 | });
12 |
--------------------------------------------------------------------------------
/tests/e2e/specs/example.spec.js:
--------------------------------------------------------------------------------
1 | // https://docs.cypress.io/api/introduction/api.html
2 |
3 | describe("My First Test", () => {
4 | it("Visits the app root url", () => {
5 | cy.visit("/");
6 | cy.contains("h2", "Welcome to Your Vue.js + TypeScript dApp");
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/public/img/icons/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/shims-tsx.d.ts:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from "vue";
2 |
3 | declare global {
4 | namespace JSX {
5 | // tslint:disable no-empty-interface
6 | interface Element extends VNode {}
7 | // tslint:disable no-empty-interface
8 | interface ElementClass extends Vue {}
9 | interface IntrinsicElements {
10 | [elem: string]: any;
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/public/img/icons/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-144x144.png",
7 | "sizes": "144x144",
8 | "type": "image/png"
9 | }
10 | ],
11 | "theme_color": "#ffffff",
12 | "background_color": "#ffffff",
13 | "display": "standalone"
14 | }
15 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | # Contributors
2 |
3 | ## Special thanks for all the people who had helped this project so far:
4 |
5 | * [Dekan Brown](https://github.com/dekanbro)
6 | * [Wolflo](https://github.com/wolflo)
7 | * [Sam kuhlmann](https://github.com/skuhlmann)
8 | * [Tommy](https://github.com/proofoftom)
9 | * [Ven Gist](https://github.com/oovg)
10 | * [TomAFrench](https://github.com/TomAFrench)
11 |
--------------------------------------------------------------------------------
/tests/unit/example.spec.ts:
--------------------------------------------------------------------------------
1 | import { expect } from "chai";
2 | import { shallowMount } from "@vue/test-utils";
3 | import HelloWorld from "@/components/HelloWorld.vue";
4 |
5 | describe("HelloWorld.vue", () => {
6 | it("renders props.msg when passed", () => {
7 | const msg = "new message";
8 | const wrapper = shallowMount(HelloWorld, {
9 | propsData: { msg }
10 | });
11 | expect(wrapper.text()).to.include(msg);
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | /tests/e2e/videos/
6 | /tests/e2e/screenshots/
7 |
8 | # local env files
9 | .env.local
10 | .env.*.local
11 | .env
12 |
13 | # Log files
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 |
18 | # Editor directories and files
19 | .idea
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
26 | # Build specific files
27 | build
28 | cache
29 | .openzeppelin/.session
30 | .openzeppelin/dev-*.json
31 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.codeActionsOnSave": {
3 | "source.fixAll": true
4 | },
5 | "editor.defaultFormatter": "esbenp.prettier-vscode",
6 | "eslint.packageManager": "yarn",
7 | "eslint.validate": [
8 | "vue",
9 | "json",
10 | "javascript",
11 | "javascriptreact",
12 | "typescript",
13 | "typescriptreact"
14 | ],
15 | "solidity.compileUsingRemoteVersion": "0.6.3+commit.8dda9521",
16 | "solidity.packageDefaultDependenciesContractsDirectory": ""
17 | }
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Moloch Minion
2 |
3 | A contract that allows execution of arbitrary calls voted on by members of a Moloch DAO.
4 |
5 | ## Usage
6 |
7 | ### Install the dependencies
8 | ```
9 | yarn
10 | ```
11 |
12 | #### Compile and generate type definitions for contracts
13 | ```
14 | yarn build:contracts
15 | ```
16 |
17 | #### Run Waffle tests with stack traces
18 | ```
19 | yarn test:contracts
20 | ```
21 |
22 | #### Run web
23 | ```
24 | yarn start:web
25 | ```
26 |
27 | #### build web
28 | ```
29 | yarn build:web
30 | ```
--------------------------------------------------------------------------------
/contracts/mock/RevertingMoloch.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.0;
2 |
3 | contract RevertingMoloch {
4 | address public depositToken;
5 |
6 | function submitProposal(
7 | address applicant,
8 | uint256 sharesRequested,
9 | uint256 lootRequested,
10 | uint256 tributeOffered,
11 | address tributeToken,
12 | uint256 paymentRequested,
13 | address paymentToken,
14 | string memory details
15 | ) public returns (uint256 proposalId) {
16 | revert();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 | Artboard 46
2 |
--------------------------------------------------------------------------------
/buidler.config.ts:
--------------------------------------------------------------------------------
1 | import { BuidlerConfig, usePlugin } from "@nomiclabs/buidler/config";
2 |
3 | usePlugin("@nomiclabs/buidler-waffle");
4 | usePlugin("buidler-typechain");
5 |
6 | const config: BuidlerConfig = {
7 | paths: {
8 | artifacts: "./build/artifacts",
9 | tests: "./tests/contracts"
10 | },
11 | solc: {
12 | version: "0.5.12",
13 | optimizer: {
14 | enabled: true,
15 | runs: 200
16 | }
17 | },
18 | typechain: {
19 | outDir: "./build/types",
20 | target: "ethers"
21 | }
22 | };
23 |
24 | export default config;
25 |
--------------------------------------------------------------------------------
/tests/contracts/utils/types.ts:
--------------------------------------------------------------------------------
1 | import { ethers } from "ethers";
2 |
3 | interface Action {
4 | to: string;
5 | value: ethers.utils.BigNumber;
6 | data: string;
7 | description: string;
8 | proposalId: number;
9 | queueIndex: number;
10 | }
11 |
12 | interface Proposal {
13 | applicant: string;
14 | proposer: string;
15 | sharesRequested: number;
16 | lootRequested: number;
17 | tributeOffered: number;
18 | tributeToken: string;
19 | paymentRequested: number;
20 | paymentToken: string;
21 | details: string;
22 | }
23 |
24 | export { Action, Proposal };
25 |
--------------------------------------------------------------------------------
/contracts/mock/TargetMock.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.0;
2 |
3 | contract TargetMock {
4 |
5 | event Called(
6 | address indexed caller,
7 | uint indexed value,
8 | bytes data
9 | );
10 |
11 | function fail() external payable {
12 | revert();
13 | }
14 |
15 | function() external payable {
16 | // bytes memory data;
17 | // assembly{
18 | // let _size := calldatasize
19 | // mstore(data, _size)
20 | // calldatacopy(add(data, 0x20), 0x00, size)
21 | // }
22 | // emit Called(msg.sender, msg.value, data);
23 | emit Called(msg.sender, msg.value, msg.data);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Moloch Minion
9 |
10 |
11 |
12 |
13 | We're sorry but Moloch Minion doesn't work properly without JavaScript enabled. Please enable it to continue.
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: [
7 | "plugin:vue/essential",
8 | "eslint:recommended",
9 | "@vue/typescript/recommended",
10 | "@vue/prettier",
11 | "@vue/prettier/@typescript-eslint"
12 | ],
13 | parserOptions: {
14 | ecmaVersion: 2020
15 | },
16 | rules: {
17 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
18 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
19 | },
20 | overrides: [
21 | {
22 | files: [
23 | "**/__tests__/*.{j,t}s?(x)",
24 | "**/tests/unit/**/*.spec.{j,t}s?(x)"
25 | ],
26 | env: {
27 | mocha: true
28 | }
29 | }
30 | ]
31 | };
32 |
--------------------------------------------------------------------------------
/tests/e2e/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import "./commands";
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
21 |
--------------------------------------------------------------------------------
/contracts/moloch/oz/IERC20.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.2;
2 |
3 | interface IERC20 {
4 | function transfer(address to, uint256 value) external returns (bool);
5 |
6 | function approve(address spender, uint256 value) external returns (bool);
7 |
8 | function transferFrom(address from, address to, uint256 value) external returns (bool);
9 |
10 | function totalSupply() external view returns (uint256);
11 |
12 | function balanceOf(address who) external view returns (uint256);
13 |
14 | function allowance(address owner, address spender) external view returns (uint256);
15 |
16 | event Transfer(address indexed from, address indexed to, uint256 value);
17 |
18 | event Approval(address indexed owner, address indexed spender, uint256 value);
19 | }
20 |
--------------------------------------------------------------------------------
/src/views/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 | About
15 |
16 | There was no way built into Moloch V2 to run arbitrary functions from
17 | different contracts through a passing proposal. This now works through
18 | a 'Minion' contract, through a funding proposal in V2 with 0 shares.
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/contracts/mock/Token.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.2;
2 |
3 | import "../moloch/oz/ERC20.sol";
4 |
5 | contract Token is ERC20 {
6 | bool transfersEnabled = true;
7 | bool transfersReturningFalse = false;
8 |
9 | constructor(uint256 supply) public {
10 | _mint(msg.sender, supply);
11 | }
12 |
13 | function updateTransfersEnabled(bool enabled) external {
14 | transfersEnabled = enabled;
15 | }
16 |
17 | function updateTransfersReturningFalse(bool enabled) external {
18 | transfersReturningFalse = enabled;
19 | }
20 |
21 | function transfer(address to, uint256 value) public returns (bool) {
22 | if (transfersReturningFalse) {
23 | return false;
24 | }
25 | require(transfersEnabled);
26 | return super.transfer(to, value);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/contracts/moloch/tokens/Token.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.2;
2 |
3 | import "../oz/ERC20.sol";
4 |
5 | contract Token is ERC20 {
6 | bool transfersEnabled = true;
7 | bool transfersReturningFalse = false;
8 |
9 | constructor(uint256 supply) public {
10 | _mint(msg.sender, supply);
11 | }
12 |
13 | function updateTransfersEnabled(bool enabled) external {
14 | transfersEnabled = enabled;
15 | }
16 |
17 | function updateTransfersReturningFalse(bool enabled) external {
18 | transfersReturningFalse = enabled;
19 | }
20 |
21 | function transfer(address to, uint256 value) public returns (bool) {
22 | if (transfersReturningFalse) {
23 | return false;
24 | }
25 | require(transfersEnabled);
26 | return super.transfer(to, value);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/router/index.ts:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import VueRouter from "vue-router";
3 | import Home from "../views/Home.vue";
4 | import About from "../views/About.vue";
5 | import NewMinion from "../views/NewMinion.vue";
6 | import Ens from "../views/Ens.vue";
7 |
8 | Vue.use(VueRouter);
9 |
10 | const routes = [
11 | {
12 | path: "/about/:minion?",
13 | name: "About",
14 | component: About
15 | },
16 | {
17 | path: "/new/:minion?",
18 | name: "New Minion",
19 | component: NewMinion
20 | },
21 | {
22 | path: "/ens/:minion?",
23 | name: "ENS",
24 | component: Ens
25 | },
26 | {
27 | path: "/:minion?",
28 | name: "Home",
29 | component: Home
30 | }
31 | ];
32 |
33 | const router = new VueRouter({
34 | mode: "history",
35 | base: process.env.BASE_URL,
36 | routes
37 | });
38 |
39 | export default router;
40 |
--------------------------------------------------------------------------------
/contracts/moloch/oz/SafeMath.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.2;
2 |
3 | library SafeMath {
4 | function mul(uint256 a, uint256 b) internal pure returns (uint256) {
5 | if (a == 0) {
6 | return 0;
7 | }
8 |
9 | uint256 c = a * b;
10 | require(c / a == b);
11 |
12 | return c;
13 | }
14 |
15 | function div(uint256 a, uint256 b) internal pure returns (uint256) {
16 |
17 | require(b > 0);
18 | uint256 c = a / b;
19 |
20 | return c;
21 | }
22 |
23 | function sub(uint256 a, uint256 b) internal pure returns (uint256) {
24 | require(b <= a);
25 | uint256 c = a - b;
26 |
27 | return c;
28 | }
29 |
30 | function add(uint256 a, uint256 b) internal pure returns (uint256) {
31 | uint256 c = a + b;
32 | require(c >= a);
33 |
34 | return c;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App.vue";
3 | import "./registerServiceWorker";
4 | import router from "./router";
5 | import vuetify from "./plugins/vuetify";
6 | import VueApollo from "vue-apollo";
7 | import ApolloClient from "apollo-boost";
8 |
9 | Vue.use(VueApollo);
10 | Vue.config.productionTip = false;
11 |
12 | const graphURI = {
13 | kovan:
14 | "https://api.thegraph.com/subgraphs/name/odyssy-automaton/daohaus-kovan",
15 | mainnet: "https://api.thegraph.com/subgraphs/name/odyssy-automaton/daohaus"
16 | };
17 |
18 | const apolloClient = new ApolloClient({
19 | // You should use an absolute URL here
20 | uri: process.env.VUE_APP_CHAIN === "kovan" ? graphURI.kovan : graphURI.mainnet
21 | });
22 |
23 | const apolloProvider = new VueApollo({
24 | defaultClient: apolloClient
25 | });
26 |
27 | new Vue({
28 | router,
29 | vuetify,
30 | apolloProvider,
31 | render: h => h(App)
32 | }).$mount("#app");
33 |
--------------------------------------------------------------------------------
/tests/e2e/support/commands.js:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 | //
11 | //
12 | // -- This is a parent command --
13 | // Cypress.Commands.add("login", (email, password) => { ... })
14 | //
15 | //
16 | // -- This is a child command --
17 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
18 | //
19 | //
20 | // -- This is a dual command --
21 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
22 | //
23 | //
24 | // -- This is will overwrite an existing command --
25 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
26 |
--------------------------------------------------------------------------------
/tests/contracts/utils/constants.ts:
--------------------------------------------------------------------------------
1 | import { ethers } from "ethers";
2 |
3 | const MINION_ACTION_DETAILS =
4 | '{"isMinion": true, "title":"MINION", "description":"';
5 |
6 | const molochConfig = {
7 | PERIOD_DURATION_IN_SECONDS: 17280,
8 | VOTING_DURATON_IN_PERIODS: 35,
9 | GRACE_DURATON_IN_PERIODS: 35,
10 | PROPOSAL_DEPOSIT: 10,
11 | DILUTION_BOUND: 3,
12 | PROCESSING_REWARD: 1,
13 | TOKEN_SUPPLY: 10000
14 | };
15 |
16 | const revertStrings = {
17 | none: "revert",
18 | INVALID_PROP_TARGET: "Minion::invalid _actionTo",
19 | INVALID_EXEC_TARGET: "Minion::invalid target",
20 | INVALID_EXEC_ID: "Minion::invalid _proposalId",
21 | IS_EXECUTED: "Minion::action executed",
22 | NO_ETH: "Minion::insufficient eth",
23 | NOT_PASSED: "Minion::proposal not passed",
24 | CALL_FAIL: "Minion::call failure"
25 | };
26 |
27 | const systemConstants = {
28 | MINION_ACTION_DETAILS,
29 | molochConfig,
30 | revertStrings
31 | };
32 |
33 | export default { ...ethers.constants, ...systemConstants };
34 |
--------------------------------------------------------------------------------
/tests/e2e/plugins/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable arrow-body-style */
2 | // https://docs.cypress.io/guides/guides/plugins-guide.html
3 |
4 | // if you need a custom webpack configuration you can uncomment the following import
5 | // and then use the `file:preprocessor` event
6 | // as explained in the cypress docs
7 | // https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples
8 |
9 | // /* eslint-disable import/no-extraneous-dependencies, global-require */
10 | // const webpack = require('@cypress/webpack-preprocessor')
11 |
12 | module.exports = (on, config) => {
13 | // on('file:preprocessor', webpack({
14 | // webpackOptions: require('@vue/cli-service/webpack.config'),
15 | // watchOptions: {}
16 | // }))
17 |
18 | return Object.assign({}, config, {
19 | fixturesFolder: "tests/e2e/fixtures",
20 | integrationFolder: "tests/e2e/specs",
21 | screenshotsFolder: "tests/e2e/screenshots",
22 | videosFolder: "tests/e2e/videos",
23 | supportFile: "tests/e2e/support/index.js"
24 | });
25 | };
26 |
--------------------------------------------------------------------------------
/src/abi/moloch_v2_guildbank.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "constant": false,
4 | "inputs": [
5 | {
6 | "name": "token",
7 | "type": "address"
8 | },
9 | {
10 | "name": "receiver",
11 | "type": "address"
12 | },
13 | {
14 | "name": "amount",
15 | "type": "uint256"
16 | }
17 | ],
18 | "name": "withdrawToken",
19 | "outputs": [
20 | {
21 | "name": "",
22 | "type": "bool"
23 | }
24 | ],
25 | "payable": false,
26 | "stateMutability": "nonpayable",
27 | "type": "function"
28 | },
29 | {
30 | "constant": false,
31 | "inputs": [
32 | {
33 | "name": "receiver",
34 | "type": "address"
35 | },
36 | {
37 | "name": "shares",
38 | "type": "uint256"
39 | },
40 | {
41 | "name": "totalShares",
42 | "type": "uint256"
43 | },
44 | {
45 | "name": "approvedTokens",
46 | "type": "address[]"
47 | }
48 | ],
49 | "name": "withdraw",
50 | "outputs": [
51 | {
52 | "name": "",
53 | "type": "bool"
54 | }
55 | ],
56 | "payable": false,
57 | "stateMutability": "nonpayable",
58 | "type": "function"
59 | }
60 | ]
61 |
--------------------------------------------------------------------------------
/src/registerServiceWorker.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | import { register } from "register-service-worker";
4 |
5 | if (process.env.NODE_ENV === "production") {
6 | register(`${process.env.BASE_URL}service-worker.js`, {
7 | ready() {
8 | console.log(
9 | "App is being served from cache by a service worker.\n" +
10 | "For more details, visit https://goo.gl/AFskqB"
11 | );
12 | },
13 | registered() {
14 | console.log("Service worker has been registered.");
15 | },
16 | cached() {
17 | console.log("Content has been cached for offline use.");
18 | },
19 | updatefound() {
20 | console.log("New content is downloading.");
21 | },
22 | updated() {
23 | console.log("New content is available; Refresh...");
24 | setTimeout(() => {
25 | window.location.reload(true);
26 | }, 1000);
27 | },
28 | offline() {
29 | console.log(
30 | "No internet connection found. App is running in offline mode."
31 | );
32 | },
33 | error(error) {
34 | console.error("Error during service worker registration:", error);
35 | }
36 | });
37 | }
38 |
--------------------------------------------------------------------------------
/contracts/moloch/MolochSummoner.sol:
--------------------------------------------------------------------------------
1 | pragma solidity 0.5.12;
2 |
3 | import "./Moloch.sol";
4 |
5 | contract MolochSummoner {
6 |
7 | Moloch private M;
8 |
9 | address[] public Molochs;
10 |
11 | event Summoned(address indexed M, address indexed _summoner);
12 |
13 | function summonMoloch(
14 | address _summoner,
15 | address[] memory _approvedTokens,
16 | uint256 _periodDuration,
17 | uint256 _votingPeriodLength,
18 | uint256 _gracePeriodLength,
19 | uint256 _proposalDeposit,
20 | uint256 _dilutionBound,
21 | uint256 _processingReward) public {
22 |
23 | M = new Moloch(
24 | _summoner,
25 | _approvedTokens,
26 | _periodDuration,
27 | _votingPeriodLength,
28 | _gracePeriodLength,
29 | _proposalDeposit,
30 | _dilutionBound,
31 | _processingReward);
32 |
33 | Molochs.push(address(M));
34 |
35 | emit Summoned(address(M), _summoner);
36 |
37 | }
38 |
39 | function getMolochCount() public view returns (uint256 MolochCount) {
40 | return Molochs.length;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/contracts/moloch/oz/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2019 zOS Global Limited
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included
14 | in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 | No Minion Proposals yet.
15 |
21 |
27 |
28 |
29 |
30 |
31 |
56 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "commonjs",
5 | "strict": true,
6 | "jsx": "preserve",
7 | "importHelpers": true,
8 | "moduleResolution": "node",
9 | "experimentalDecorators": true,
10 | "esModuleInterop": true,
11 | "outDir": "dist",
12 | "resolveJsonModule": true,
13 | "allowSyntheticDefaultImports": true,
14 | "allowJs": true,
15 | "sourceMap": true,
16 | "baseUrl": ".",
17 | "typeRoots": [
18 | "./node_modules/@types",
19 | "./node_modules/vuetify/types"
20 | ],
21 | "types": [
22 | "webpack-env",
23 | "mocha",
24 | "chai",
25 | "vuetify"
26 | ],
27 | "paths": {
28 | "@/*": [
29 | "src/*"
30 | ]
31 | },
32 | "lib": [
33 | "esnext",
34 | "dom",
35 | "dom.iterable",
36 | "scripthost"
37 | ]
38 | },
39 | "include": [
40 | "src/**/*.ts",
41 | "src/**/*.tsx",
42 | "src/**/*.vue",
43 | "tests/**/*.ts",
44 | "tests/**/*.tsx",
45 | "./scripts",
46 | "./test"
47 | ],
48 | "exclude": [
49 | "node_modules"
50 | ],
51 | "files": [
52 | "./buidler.config.ts",
53 | "./node_modules/@nomiclabs/buidler-ethers/src/type-extensions.d.ts",
54 | "./node_modules/@nomiclabs/buidler-waffle/src/type-extensions.d.ts",
55 | "node_modules/buidler-typechain/src/type-extensions.d.ts"
56 | ]
57 | }
58 |
--------------------------------------------------------------------------------
/contracts/moloch/test-helpers/Submitter.sol:
--------------------------------------------------------------------------------
1 | // helper for testing moloch.submitProposal return value
2 |
3 | pragma solidity 0.5.12;
4 |
5 | import "../Moloch.sol";
6 |
7 | contract Submitter {
8 |
9 | event Submit(uint256 proposalId);
10 |
11 | Moloch public moloch; // moloch contract reference
12 |
13 | constructor(address molochAddress) public {
14 | moloch = Moloch(molochAddress);
15 | }
16 |
17 | function submitProposal(
18 | address applicant,
19 | uint256 sharesRequested,
20 | uint256 lootRequested,
21 | uint256 tributeOffered,
22 | address tributeToken,
23 | uint256 paymentRequested,
24 | address paymentToken,
25 | string memory details
26 | ) public {
27 | uint256 proposalId = moloch.submitProposal(
28 | applicant,
29 | sharesRequested,
30 | lootRequested,
31 | tributeOffered,
32 | tributeToken,
33 | paymentRequested,
34 | paymentToken,
35 | details
36 | );
37 |
38 | emit Submit(proposalId);
39 | }
40 |
41 | function submitWhitelistProposal(
42 | address tokenToWhitelist,
43 | string memory details
44 | ) public {
45 | uint256 proposalId = moloch.submitWhitelistProposal(
46 | tokenToWhitelist,
47 | details
48 | );
49 |
50 | emit Submit(proposalId);
51 | }
52 |
53 | function submitGuildKickProposal(
54 | address memberToKick,
55 | string memory details
56 | ) public {
57 | uint256 proposalId = moloch.submitGuildKickProposal(
58 | memberToKick,
59 | details
60 | );
61 |
62 | emit Submit(proposalId);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/components/MinionItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Minion: {{ minion.proposalId }}
11 |
12 | {{ minion.description }}
13 |
14 | executed
15 |
16 |
17 | Execute
23 | Details
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
57 |
--------------------------------------------------------------------------------
/tests/contracts/utils/utils.ts:
--------------------------------------------------------------------------------
1 | import { ethereum } from "@nomiclabs/buidler";
2 | import { ethers } from "ethers";
3 |
4 | import { Action } from "./types";
5 | import Constants from "./constants";
6 | import { Moloch } from "../../../build/types/Moloch";
7 | import { Minion } from "../../../build/types/Minion";
8 |
9 | const molochConfig = Constants.molochConfig;
10 |
11 | function encodeDetailsString(actionDescription: string) {
12 | return Constants.MINION_ACTION_DETAILS + actionDescription + '"}';
13 | }
14 |
15 | async function incProposalCount(moloch: Moloch, n: number) {
16 | const token = await moloch.depositToken();
17 | for (let i = 0; i < n; i++) {
18 | await moloch.submitProposal(moloch.address, 0, 0, 0, token, 0, token, "");
19 | }
20 | }
21 |
22 | async function bumpTime(periods: number, duration: number) {
23 | const timeIncrease = periods * duration;
24 | await ethereum.send("evm_increaseTime", [timeIncrease]);
25 | await ethereum.send("evm_mine", []);
26 | }
27 |
28 | async function passProposal(moloch: Moloch, action: Action) {
29 | await moloch.sponsorProposal(action.proposalId);
30 | await bumpTime(1, molochConfig.PERIOD_DURATION_IN_SECONDS);
31 | await moloch.submitVote(action.queueIndex, 1);
32 | await bumpTime(
33 | molochConfig.VOTING_DURATON_IN_PERIODS,
34 | molochConfig.PERIOD_DURATION_IN_SECONDS
35 | );
36 | await bumpTime(
37 | molochConfig.GRACE_DURATON_IN_PERIODS,
38 | molochConfig.PERIOD_DURATION_IN_SECONDS
39 | );
40 | await moloch.processProposal(action.queueIndex);
41 | }
42 |
43 | async function proposeAndPass(minion: Minion, moloch: Moloch, action: Action) {
44 | await minion.proposeAction(
45 | action.to,
46 | action.value,
47 | action.data,
48 | action.description
49 | );
50 | await passProposal(moloch, action);
51 | }
52 |
53 | export default {
54 | bumpTime,
55 | passProposal,
56 | proposeAndPass,
57 | incProposalCount,
58 | encodeDetailsString
59 | };
60 |
--------------------------------------------------------------------------------
/public/service-worker.js:
--------------------------------------------------------------------------------
1 | // service-worker.js
2 |
3 | workbox.core.setCacheNameDetails({ prefix: "d4" });
4 | //Change this value every time before you build
5 | const LATEST_VERSION = "v0.1";
6 | self.addEventListener("activate", event => {
7 | console.log(`%c ${LATEST_VERSION} `, "background: #ddd; color: #0000ff");
8 | if (caches) {
9 | caches.keys().then(arr => {
10 | arr.forEach(key => {
11 | if (key.indexOf("d4-precache") < -1) {
12 | caches
13 | .delete(key)
14 | .then(() =>
15 | console.log(
16 | `%c Cleared ${key}`,
17 | "background: #333; color: #ff0000"
18 | )
19 | );
20 | } else {
21 | caches.open(key).then(cache => {
22 | cache.match("version").then(res => {
23 | if (!res) {
24 | cache.put(
25 | "version",
26 | new Response(LATEST_VERSION, {
27 | status: 200,
28 | statusText: LATEST_VERSION
29 | })
30 | );
31 | } else if (res.statusText !== LATEST_VERSION) {
32 | caches
33 | .delete(key)
34 | .then(() =>
35 | console.log(
36 | `%c Cleared Cache ${LATEST_VERSION}`,
37 | "background: #333; color: #ff0000"
38 | )
39 | );
40 | } else
41 | console.log(
42 | `%c Great you have the latest version ${LATEST_VERSION}`,
43 | "background: #333; color: #00ff00"
44 | );
45 | });
46 | });
47 | }
48 | });
49 | });
50 | }
51 | });
52 |
53 | workbox.skipWaiting();
54 | workbox.clientsClaim();
55 |
56 | self.__precacheManifest = [].concat(self.__precacheManifest || []);
57 | workbox.precaching.suppressWarnings();
58 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
59 |
--------------------------------------------------------------------------------
/contracts/moloch/oz/ReentrancyGuard.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.0;
2 |
3 | /**
4 | * @dev Contract module that helps prevent reentrant calls to a function.
5 | *
6 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
7 | * available, which can be applied to functions to make sure there are no nested
8 | * (reentrant) calls to them.
9 | *
10 | * Note that because there is a single `nonReentrant` guard, functions marked as
11 | * `nonReentrant` may not call one another. This can be worked around by making
12 | * those functions `private`, and then adding `external` `nonReentrant` entry
13 | * points to them.
14 | *
15 | * _Since v2.5.0:_ this module is now much more gas efficient, given net gas
16 | * metering changes introduced in the Istanbul hardfork.
17 | */
18 | contract ReentrancyGuard {
19 | bool private _notEntered;
20 |
21 | constructor () internal {
22 | // Storing an initial non-zero value makes deployment a bit more
23 | // expensive, but in exchange the refund on every call to nonReentrant
24 | // will be lower in amount. Since refunds are capped to a percetange of
25 | // the total transaction's gas, it is best to keep them low in cases
26 | // like this one, to increase the likelihood of the full refund coming
27 | // into effect.
28 | _notEntered = true;
29 | }
30 |
31 | /**
32 | * @dev Prevents a contract from calling itself, directly or indirectly.
33 | * Calling a `nonReentrant` function from another `nonReentrant`
34 | * function is not supported. It is possible to prevent this from happening
35 | * by making the `nonReentrant` function external, and make it call a
36 | * `private` function that does the actual work.
37 | */
38 | modifier nonReentrant() {
39 | // On the first call to nonReentrant, _notEntered will be true
40 | require(_notEntered, "ReentrancyGuard: reentrant call");
41 |
42 | // Any calls to nonReentrant after this point will fail
43 | _notEntered = false;
44 |
45 | _;
46 |
47 | // By storing the original value once again, a refund is triggered (see
48 | // https://eips.ethereum.org/EIPS/eip-2200)
49 | _notEntered = true;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/contracts/Minion.sol:
--------------------------------------------------------------------------------
1 | pragma solidity 0.5.12;
2 |
3 | import "./moloch/Moloch.sol";
4 |
5 | contract Minion {
6 |
7 | string public constant MINION_ACTION_DETAILS = '{"isMinion": true, "title":"MINION", "description":"';
8 |
9 | Moloch public moloch;
10 | address public molochApprovedToken;
11 | mapping (uint256 => Action) public actions; // proposalId => Action
12 |
13 | struct Action {
14 | uint256 value;
15 | address to;
16 | address proposer;
17 | bool executed;
18 | bytes data;
19 | }
20 |
21 | event ActionProposed(uint256 proposalId, address proposer);
22 | event ActionExecuted(uint256 proposalId, address executor);
23 |
24 | constructor(address _moloch) public {
25 | moloch = Moloch(_moloch);
26 | molochApprovedToken = moloch.depositToken();
27 | }
28 |
29 | // withdraw funds from the moloch
30 | function doWithdraw(address _token, uint256 _amount) public {
31 | moloch.withdrawBalance(_token, _amount);
32 | }
33 |
34 | function proposeAction(
35 | address _actionTo,
36 | uint256 _actionValue,
37 | bytes memory _actionData,
38 | string memory _description
39 | )
40 | public
41 | returns (uint256)
42 | {
43 | // No calls to zero address allows us to check that Minion submitted
44 | // the proposal without getting the proposal struct from the moloch
45 | require(_actionTo != address(0), "Minion::invalid _actionTo");
46 |
47 | string memory details = string(abi.encodePacked(MINION_ACTION_DETAILS, _description, '"}'));
48 |
49 | uint256 proposalId = moloch.submitProposal(
50 | address(this),
51 | 0,
52 | 0,
53 | 0,
54 | molochApprovedToken,
55 | 0,
56 | molochApprovedToken,
57 | details
58 | );
59 |
60 | Action memory action = Action({
61 | value: _actionValue,
62 | to: _actionTo,
63 | proposer: msg.sender,
64 | executed: false,
65 | data: _actionData
66 | });
67 |
68 | actions[proposalId] = action;
69 |
70 | emit ActionProposed(proposalId, msg.sender);
71 | return proposalId;
72 | }
73 |
74 | function executeAction(uint256 _proposalId) public returns (bytes memory) {
75 | Action memory action = actions[_proposalId];
76 | bool[6] memory flags = moloch.getProposalFlags(_proposalId);
77 |
78 | // minion did not submit this proposal
79 | require(action.to != address(0), "Minion::invalid _proposalId");
80 | // can't call arbitrary functions on parent moloch
81 | require(action.to != address(moloch), "Minion::invalid target");
82 | require(!action.executed, "Minion::action executed");
83 | require(address(this).balance >= action.value, "Minion::insufficient eth");
84 | require(flags[2], "Minion::proposal not passed");
85 |
86 | // execute call
87 | actions[_proposalId].executed = true;
88 | (bool success, bytes memory retData) = action.to.call.value(action.value)(action.data);
89 | require(success, "Minion::call failure");
90 | emit ActionExecuted(_proposalId, msg.sender);
91 | return retData;
92 | }
93 |
94 | function() external payable { }
95 | }
96 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "buidler-waffle-typechain-vue",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "yarn build:contracts && yarn build:web",
7 | "build:contracts": "buidler typechain",
8 | "build:web": "vue-cli-service build",
9 | "clean": "rm -rf cache && rm -rf build",
10 | "deploy:local": "yarn clean && yarn build:contracts",
11 | "lint": "vue-cli-service lint",
12 | "start:dev": "yarn deploy:local && vue-cli-service serve",
13 | "start:node": "buidler node",
14 | "start:web": "vue-cli-service serve",
15 | "test": "yarn test:contracts && yarn test:unit && yarn test:e2e",
16 | "test:contracts": "buidler test",
17 | "test:e2e": "vue-cli-service test:e2e",
18 | "test:unit": "vue-cli-service test:unit",
19 | "upgrade:local": "yarn build:contracts"
20 | },
21 | "dependencies": {
22 | "@fortawesome/fontawesome-free": "^5.8.2",
23 | "@resolver-engine/core": "^0.3.3",
24 | "@walletconnect/web3-provider": "^1.0.0-beta.47",
25 | "abi-decoder": "^2.3.0",
26 | "apollo-boost": "^0.4.7",
27 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
28 | "core-js": "^3.6.4",
29 | "ethers": "^4.0.45",
30 | "graphql": "^14.0.0",
31 | "register-service-worker": "^1.6.2",
32 | "roboto-fontface": "*",
33 | "vue": "^2.6.11",
34 | "vue-apollo": "^3.0.3",
35 | "vue-class-component": "^7.2.2",
36 | "vue-property-decorator": "^8.3.0",
37 | "vue-router": "^3.1.5",
38 | "vuetify": "^2.2.11",
39 | "vuex": "^3.1.2",
40 | "web3modal": "^1.3.0"
41 | },
42 | "devDependencies": {
43 | "@nomiclabs/buidler": "^1.2.0",
44 | "@nomiclabs/buidler-ethers": "^1.2.0",
45 | "@nomiclabs/buidler-waffle": "^1.2.0",
46 | "@types/chai": "^4.2.9",
47 | "@types/mocha": "^7.0.1",
48 | "@types/node": "^13.7.7",
49 | "@typescript-eslint/eslint-plugin": "^2.18.0",
50 | "@typescript-eslint/parser": "^2.18.0",
51 | "@vue/cli-plugin-babel": "~4.2.0",
52 | "@vue/cli-plugin-e2e-cypress": "~4.2.0",
53 | "@vue/cli-plugin-eslint": "~4.2.0",
54 | "@vue/cli-plugin-pwa": "~4.2.0",
55 | "@vue/cli-plugin-router": "~4.2.0",
56 | "@vue/cli-plugin-typescript": "~4.2.0",
57 | "@vue/cli-plugin-unit-mocha": "~4.2.0",
58 | "@vue/cli-plugin-vuex": "~4.2.0",
59 | "@vue/cli-service": "~4.2.0",
60 | "@vue/eslint-config-prettier": "^6.0.0",
61 | "@vue/eslint-config-typescript": "^5.0.1",
62 | "@vue/test-utils": "1.0.0-beta.31",
63 | "buidler-typechain": "^0.0.5",
64 | "chai": "^4.2.0",
65 | "eslint": "^6.7.2",
66 | "eslint-plugin-prettier": "^3.1.1",
67 | "eslint-plugin-vue": "^6.1.2",
68 | "ethereum-waffle": "^2.3.2",
69 | "lint-staged": "^9.5.0",
70 | "null-loader": "^3.0.0",
71 | "prettier": "^1.19.1",
72 | "sass": "^1.25.0",
73 | "sass-loader": "^8.0.2",
74 | "solc": "0.6.3",
75 | "ts-generator": "^0.0.8",
76 | "ts-node": "^8.6.2",
77 | "typechain": "^1.0.5",
78 | "typechain-target-ethers": "^1.0.3",
79 | "typechain-target-truffle": "^1.0.2",
80 | "typechain-target-web3-v1": "^1.0.4",
81 | "typescript": "^3.8.3",
82 | "vue-cli-plugin-vuetify": "~2.0.5",
83 | "vue-template-compiler": "^2.6.11",
84 | "vuetify-loader": "^1.3.0"
85 | },
86 | "gitHooks": {
87 | "pre-commit": "lint-staged"
88 | },
89 | "lint-staged": {
90 | "*.{js,jsx,vue,ts,tsx}": [
91 | "vue-cli-service lint",
92 | "git add"
93 | ]
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/views/Ens.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
19 | Register
20 | Assigned Subdomains
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
33 |
39 |
45 |
46 | Submit
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | {{ subdomain.name }}: {{ subdomain.owner }}
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | ENS Subdomain Registrar
64 |
65 | Subdomains can be requested after configuring a domain in the Minion
66 | Subdomain Registrar contract.
67 |
68 |
69 |
70 |
71 |
72 |
73 |
145 |
--------------------------------------------------------------------------------
/src/abi/minion.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "address",
6 | "name": "_moloch",
7 | "type": "address"
8 | }
9 | ],
10 | "payable": false,
11 | "stateMutability": "nonpayable",
12 | "type": "constructor"
13 | },
14 | {
15 | "anonymous": false,
16 | "inputs": [
17 | {
18 | "indexed": false,
19 | "internalType": "uint256",
20 | "name": "proposalId",
21 | "type": "uint256"
22 | },
23 | {
24 | "indexed": false,
25 | "internalType": "address",
26 | "name": "executor",
27 | "type": "address"
28 | }
29 | ],
30 | "name": "ActionExecuted",
31 | "type": "event"
32 | },
33 | {
34 | "anonymous": false,
35 | "inputs": [
36 | {
37 | "indexed": false,
38 | "internalType": "uint256",
39 | "name": "proposalId",
40 | "type": "uint256"
41 | },
42 | {
43 | "indexed": false,
44 | "internalType": "address",
45 | "name": "proposer",
46 | "type": "address"
47 | }
48 | ],
49 | "name": "ActionProposed",
50 | "type": "event"
51 | },
52 | {
53 | "payable": true,
54 | "stateMutability": "payable",
55 | "type": "fallback"
56 | },
57 | {
58 | "constant": true,
59 | "inputs": [],
60 | "name": "MINION_ACTION_DETAILS",
61 | "outputs": [
62 | {
63 | "internalType": "string",
64 | "name": "",
65 | "type": "string"
66 | }
67 | ],
68 | "payable": false,
69 | "stateMutability": "view",
70 | "type": "function"
71 | },
72 | {
73 | "constant": true,
74 | "inputs": [
75 | {
76 | "internalType": "uint256",
77 | "name": "",
78 | "type": "uint256"
79 | }
80 | ],
81 | "name": "actions",
82 | "outputs": [
83 | {
84 | "internalType": "uint256",
85 | "name": "value",
86 | "type": "uint256"
87 | },
88 | {
89 | "internalType": "address",
90 | "name": "to",
91 | "type": "address"
92 | },
93 | {
94 | "internalType": "address",
95 | "name": "proposer",
96 | "type": "address"
97 | },
98 | {
99 | "internalType": "bool",
100 | "name": "executed",
101 | "type": "bool"
102 | },
103 | {
104 | "internalType": "bytes",
105 | "name": "data",
106 | "type": "bytes"
107 | }
108 | ],
109 | "payable": false,
110 | "stateMutability": "view",
111 | "type": "function"
112 | },
113 | {
114 | "constant": false,
115 | "inputs": [
116 | {
117 | "internalType": "address",
118 | "name": "_token",
119 | "type": "address"
120 | },
121 | {
122 | "internalType": "uint256",
123 | "name": "_amount",
124 | "type": "uint256"
125 | }
126 | ],
127 | "name": "doWithdraw",
128 | "outputs": [],
129 | "payable": false,
130 | "stateMutability": "nonpayable",
131 | "type": "function"
132 | },
133 | {
134 | "constant": false,
135 | "inputs": [
136 | {
137 | "internalType": "uint256",
138 | "name": "_proposalId",
139 | "type": "uint256"
140 | }
141 | ],
142 | "name": "executeAction",
143 | "outputs": [
144 | {
145 | "internalType": "bytes",
146 | "name": "",
147 | "type": "bytes"
148 | }
149 | ],
150 | "payable": false,
151 | "stateMutability": "nonpayable",
152 | "type": "function"
153 | },
154 | {
155 | "constant": true,
156 | "inputs": [],
157 | "name": "moloch",
158 | "outputs": [
159 | {
160 | "internalType": "contract Moloch",
161 | "name": "",
162 | "type": "address"
163 | }
164 | ],
165 | "payable": false,
166 | "stateMutability": "view",
167 | "type": "function"
168 | },
169 | {
170 | "constant": true,
171 | "inputs": [],
172 | "name": "molochApprovedToken",
173 | "outputs": [
174 | {
175 | "internalType": "address",
176 | "name": "",
177 | "type": "address"
178 | }
179 | ],
180 | "payable": false,
181 | "stateMutability": "view",
182 | "type": "function"
183 | },
184 | {
185 | "constant": false,
186 | "inputs": [
187 | {
188 | "internalType": "address",
189 | "name": "_actionTo",
190 | "type": "address"
191 | },
192 | {
193 | "internalType": "uint256",
194 | "name": "_actionValue",
195 | "type": "uint256"
196 | },
197 | {
198 | "internalType": "bytes",
199 | "name": "_actionData",
200 | "type": "bytes"
201 | },
202 | {
203 | "internalType": "string",
204 | "name": "_description",
205 | "type": "string"
206 | }
207 | ],
208 | "name": "proposeAction",
209 | "outputs": [
210 | {
211 | "internalType": "uint256",
212 | "name": "",
213 | "type": "uint256"
214 | }
215 | ],
216 | "payable": false,
217 | "stateMutability": "nonpayable",
218 | "type": "function"
219 | }
220 | ]
--------------------------------------------------------------------------------
/src/abi/erc721.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "constant": true,
4 | "inputs": [
5 | {
6 | "name": "_tokenId",
7 | "type": "uint256"
8 | }
9 | ],
10 | "name": "getApproved",
11 | "outputs": [
12 | {
13 | "name": "",
14 | "type": "address"
15 | }
16 | ],
17 | "payable": false,
18 | "stateMutability": "view",
19 | "type": "function"
20 | },
21 | {
22 | "constant": false,
23 | "inputs": [
24 | {
25 | "name": "_approved",
26 | "type": "address"
27 | },
28 | {
29 | "name": "_tokenId",
30 | "type": "uint256"
31 | }
32 | ],
33 | "name": "approve",
34 | "outputs": [],
35 | "payable": true,
36 | "stateMutability": "payable",
37 | "type": "function"
38 | },
39 | {
40 | "constant": false,
41 | "inputs": [
42 | {
43 | "name": "_from",
44 | "type": "address"
45 | },
46 | {
47 | "name": "_to",
48 | "type": "address"
49 | },
50 | {
51 | "name": "_tokenId",
52 | "type": "uint256"
53 | }
54 | ],
55 | "name": "transferFrom",
56 | "outputs": [],
57 | "payable": true,
58 | "stateMutability": "payable",
59 | "type": "function"
60 | },
61 | {
62 | "constant": false,
63 | "inputs": [
64 | {
65 | "name": "_from",
66 | "type": "address"
67 | },
68 | {
69 | "name": "_to",
70 | "type": "address"
71 | },
72 | {
73 | "name": "_tokenId",
74 | "type": "uint256"
75 | }
76 | ],
77 | "name": "safeTransferFrom",
78 | "outputs": [],
79 | "payable": true,
80 | "stateMutability": "payable",
81 | "type": "function"
82 | },
83 | {
84 | "constant": true,
85 | "inputs": [
86 | {
87 | "name": "_tokenId",
88 | "type": "uint256"
89 | }
90 | ],
91 | "name": "ownerOf",
92 | "outputs": [
93 | {
94 | "name": "",
95 | "type": "address"
96 | }
97 | ],
98 | "payable": false,
99 | "stateMutability": "view",
100 | "type": "function"
101 | },
102 | {
103 | "constant": true,
104 | "inputs": [
105 | {
106 | "name": "_owner",
107 | "type": "address"
108 | }
109 | ],
110 | "name": "balanceOf",
111 | "outputs": [
112 | {
113 | "name": "",
114 | "type": "uint256"
115 | }
116 | ],
117 | "payable": false,
118 | "stateMutability": "view",
119 | "type": "function"
120 | },
121 | {
122 | "constant": false,
123 | "inputs": [
124 | {
125 | "name": "_operator",
126 | "type": "address"
127 | },
128 | {
129 | "name": "_approved",
130 | "type": "bool"
131 | }
132 | ],
133 | "name": "setApprovalForAll",
134 | "outputs": [],
135 | "payable": false,
136 | "stateMutability": "nonpayable",
137 | "type": "function"
138 | },
139 | {
140 | "constant": false,
141 | "inputs": [
142 | {
143 | "name": "_from",
144 | "type": "address"
145 | },
146 | {
147 | "name": "_to",
148 | "type": "address"
149 | },
150 | {
151 | "name": "_tokenId",
152 | "type": "uint256"
153 | },
154 | {
155 | "name": "data",
156 | "type": "bytes"
157 | }
158 | ],
159 | "name": "safeTransferFrom",
160 | "outputs": [],
161 | "payable": true,
162 | "stateMutability": "payable",
163 | "type": "function"
164 | },
165 | {
166 | "constant": true,
167 | "inputs": [
168 | {
169 | "name": "_owner",
170 | "type": "address"
171 | },
172 | {
173 | "name": "_operator",
174 | "type": "address"
175 | }
176 | ],
177 | "name": "isApprovedForAll",
178 | "outputs": [
179 | {
180 | "name": "",
181 | "type": "bool"
182 | }
183 | ],
184 | "payable": false,
185 | "stateMutability": "view",
186 | "type": "function"
187 | },
188 | {
189 | "anonymous": false,
190 | "inputs": [
191 | {
192 | "indexed": true,
193 | "name": "_from",
194 | "type": "address"
195 | },
196 | {
197 | "indexed": true,
198 | "name": "_to",
199 | "type": "address"
200 | },
201 | {
202 | "indexed": true,
203 | "name": "_tokenId",
204 | "type": "uint256"
205 | }
206 | ],
207 | "name": "Transfer",
208 | "type": "event"
209 | },
210 | {
211 | "anonymous": false,
212 | "inputs": [
213 | {
214 | "indexed": true,
215 | "name": "_owner",
216 | "type": "address"
217 | },
218 | {
219 | "indexed": true,
220 | "name": "_approved",
221 | "type": "address"
222 | },
223 | {
224 | "indexed": true,
225 | "name": "_tokenId",
226 | "type": "uint256"
227 | }
228 | ],
229 | "name": "Approval",
230 | "type": "event"
231 | },
232 | {
233 | "anonymous": false,
234 | "inputs": [
235 | {
236 | "indexed": true,
237 | "name": "_owner",
238 | "type": "address"
239 | },
240 | {
241 | "indexed": true,
242 | "name": "_operator",
243 | "type": "address"
244 | },
245 | {
246 | "indexed": false,
247 | "name": "_approved",
248 | "type": "bool"
249 | }
250 | ],
251 | "name": "ApprovalForAll",
252 | "type": "event"
253 | }
254 | ]
255 |
--------------------------------------------------------------------------------
/src/abi/erc20.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "constant": true,
4 | "inputs": [],
5 | "name": "name",
6 | "outputs": [
7 | {
8 | "name": "",
9 | "type": "string"
10 | }
11 | ],
12 | "payable": false,
13 | "stateMutability": "view",
14 | "type": "function"
15 | },
16 | {
17 | "constant": false,
18 | "inputs": [
19 | {
20 | "name": "_spender",
21 | "type": "address"
22 | },
23 | {
24 | "name": "_value",
25 | "type": "uint256"
26 | }
27 | ],
28 | "name": "approve",
29 | "outputs": [
30 | {
31 | "name": "",
32 | "type": "bool"
33 | }
34 | ],
35 | "payable": false,
36 | "stateMutability": "nonpayable",
37 | "type": "function"
38 | },
39 | {
40 | "constant": true,
41 | "inputs": [],
42 | "name": "totalSupply",
43 | "outputs": [
44 | {
45 | "name": "",
46 | "type": "uint256"
47 | }
48 | ],
49 | "payable": false,
50 | "stateMutability": "view",
51 | "type": "function"
52 | },
53 | {
54 | "constant": false,
55 | "inputs": [
56 | {
57 | "name": "_from",
58 | "type": "address"
59 | },
60 | {
61 | "name": "_to",
62 | "type": "address"
63 | },
64 | {
65 | "name": "_value",
66 | "type": "uint256"
67 | }
68 | ],
69 | "name": "transferFrom",
70 | "outputs": [
71 | {
72 | "name": "",
73 | "type": "bool"
74 | }
75 | ],
76 | "payable": false,
77 | "stateMutability": "nonpayable",
78 | "type": "function"
79 | },
80 | {
81 | "constant": true,
82 | "inputs": [],
83 | "name": "decimals",
84 | "outputs": [
85 | {
86 | "name": "",
87 | "type": "uint8"
88 | }
89 | ],
90 | "payable": false,
91 | "stateMutability": "view",
92 | "type": "function"
93 | },
94 | {
95 | "constant": true,
96 | "inputs": [
97 | {
98 | "name": "_owner",
99 | "type": "address"
100 | }
101 | ],
102 | "name": "balanceOf",
103 | "outputs": [
104 | {
105 | "name": "balance",
106 | "type": "uint256"
107 | }
108 | ],
109 | "payable": false,
110 | "stateMutability": "view",
111 | "type": "function"
112 | },
113 | {
114 | "constant": true,
115 | "inputs": [],
116 | "name": "symbol",
117 | "outputs": [
118 | {
119 | "name": "",
120 | "type": "string"
121 | }
122 | ],
123 | "payable": false,
124 | "stateMutability": "view",
125 | "type": "function"
126 | },
127 | {
128 | "constant": false,
129 | "inputs": [
130 | {
131 | "name": "_to",
132 | "type": "address"
133 | },
134 | {
135 | "name": "_value",
136 | "type": "uint256"
137 | }
138 | ],
139 | "name": "transfer",
140 | "outputs": [
141 | {
142 | "name": "",
143 | "type": "bool"
144 | }
145 | ],
146 | "payable": false,
147 | "stateMutability": "nonpayable",
148 | "type": "function"
149 | },
150 | {
151 | "constant": true,
152 | "inputs": [
153 | {
154 | "name": "_owner",
155 | "type": "address"
156 | },
157 | {
158 | "name": "_spender",
159 | "type": "address"
160 | }
161 | ],
162 | "name": "allowance",
163 | "outputs": [
164 | {
165 | "name": "",
166 | "type": "uint256"
167 | }
168 | ],
169 | "payable": false,
170 | "stateMutability": "view",
171 | "type": "function"
172 | },
173 | {
174 | "payable": true,
175 | "stateMutability": "payable",
176 | "type": "fallback"
177 | },
178 | {
179 | "anonymous": false,
180 | "inputs": [
181 | {
182 | "indexed": true,
183 | "name": "owner",
184 | "type": "address"
185 | },
186 | {
187 | "indexed": true,
188 | "name": "spender",
189 | "type": "address"
190 | },
191 | {
192 | "indexed": false,
193 | "name": "value",
194 | "type": "uint256"
195 | }
196 | ],
197 | "name": "Approval",
198 | "type": "event"
199 | },
200 | {
201 | "anonymous": false,
202 | "inputs": [
203 | {
204 | "indexed": true,
205 | "name": "from",
206 | "type": "address"
207 | },
208 | {
209 | "indexed": true,
210 | "name": "to",
211 | "type": "address"
212 | },
213 | {
214 | "indexed": false,
215 | "name": "value",
216 | "type": "uint256"
217 | }
218 | ],
219 | "name": "Transfer",
220 | "type": "event"
221 | }
222 | ]
223 |
--------------------------------------------------------------------------------
/src/abi/moloch_v1_pool.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "constant": false,
4 | "inputs": [
5 | {
6 | "name": "sharesToBurn",
7 | "type": "uint256"
8 | }
9 | ],
10 | "name": "withdraw",
11 | "outputs": [],
12 | "payable": false,
13 | "stateMutability": "nonpayable",
14 | "type": "function"
15 | },
16 | {
17 | "constant": false,
18 | "inputs": [
19 | {
20 | "name": "newKeepers",
21 | "type": "address[]"
22 | }
23 | ],
24 | "name": "addKeepers",
25 | "outputs": [],
26 | "payable": false,
27 | "stateMutability": "nonpayable",
28 | "type": "function"
29 | },
30 | {
31 | "constant": true,
32 | "inputs": [],
33 | "name": "currentProposalIndex",
34 | "outputs": [
35 | {
36 | "name": "",
37 | "type": "uint256"
38 | }
39 | ],
40 | "payable": false,
41 | "stateMutability": "view",
42 | "type": "function"
43 | },
44 | {
45 | "constant": true,
46 | "inputs": [],
47 | "name": "moloch",
48 | "outputs": [
49 | {
50 | "name": "",
51 | "type": "address"
52 | }
53 | ],
54 | "payable": false,
55 | "stateMutability": "view",
56 | "type": "function"
57 | },
58 | {
59 | "constant": true,
60 | "inputs": [],
61 | "name": "totalPoolShares",
62 | "outputs": [
63 | {
64 | "name": "",
65 | "type": "uint256"
66 | }
67 | ],
68 | "payable": false,
69 | "stateMutability": "view",
70 | "type": "function"
71 | },
72 | {
73 | "constant": false,
74 | "inputs": [
75 | {
76 | "name": "initialTokens",
77 | "type": "uint256"
78 | },
79 | {
80 | "name": "initialPoolShares",
81 | "type": "uint256"
82 | }
83 | ],
84 | "name": "activate",
85 | "outputs": [],
86 | "payable": false,
87 | "stateMutability": "nonpayable",
88 | "type": "function"
89 | },
90 | {
91 | "constant": false,
92 | "inputs": [
93 | {
94 | "name": "sharesToBurn",
95 | "type": "uint256"
96 | },
97 | {
98 | "name": "recipient",
99 | "type": "address"
100 | }
101 | ],
102 | "name": "keeperWithdraw",
103 | "outputs": [],
104 | "payable": false,
105 | "stateMutability": "nonpayable",
106 | "type": "function"
107 | },
108 | {
109 | "constant": false,
110 | "inputs": [
111 | {
112 | "name": "toIndex",
113 | "type": "uint256"
114 | }
115 | ],
116 | "name": "sync",
117 | "outputs": [],
118 | "payable": false,
119 | "stateMutability": "nonpayable",
120 | "type": "function"
121 | },
122 | {
123 | "constant": false,
124 | "inputs": [
125 | {
126 | "name": "tokenAmount",
127 | "type": "uint256"
128 | }
129 | ],
130 | "name": "deposit",
131 | "outputs": [],
132 | "payable": false,
133 | "stateMutability": "nonpayable",
134 | "type": "function"
135 | },
136 | {
137 | "constant": true,
138 | "inputs": [],
139 | "name": "approvedToken",
140 | "outputs": [
141 | {
142 | "name": "",
143 | "type": "address"
144 | }
145 | ],
146 | "payable": false,
147 | "stateMutability": "view",
148 | "type": "function"
149 | },
150 | {
151 | "constant": true,
152 | "inputs": [
153 | {
154 | "name": "",
155 | "type": "address"
156 | }
157 | ],
158 | "name": "donors",
159 | "outputs": [
160 | {
161 | "name": "shares",
162 | "type": "uint256"
163 | }
164 | ],
165 | "payable": false,
166 | "stateMutability": "view",
167 | "type": "function"
168 | },
169 | {
170 | "constant": false,
171 | "inputs": [
172 | {
173 | "name": "keepersToRemove",
174 | "type": "address[]"
175 | }
176 | ],
177 | "name": "removeKeepers",
178 | "outputs": [],
179 | "payable": false,
180 | "stateMutability": "nonpayable",
181 | "type": "function"
182 | },
183 | {
184 | "inputs": [
185 | {
186 | "name": "_moloch",
187 | "type": "address"
188 | }
189 | ],
190 | "payable": false,
191 | "stateMutability": "nonpayable",
192 | "type": "constructor"
193 | },
194 | {
195 | "anonymous": false,
196 | "inputs": [
197 | {
198 | "indexed": false,
199 | "name": "currentProposalIndex",
200 | "type": "uint256"
201 | }
202 | ],
203 | "name": "Sync",
204 | "type": "event"
205 | },
206 | {
207 | "anonymous": false,
208 | "inputs": [
209 | {
210 | "indexed": false,
211 | "name": "donor",
212 | "type": "address"
213 | },
214 | {
215 | "indexed": false,
216 | "name": "sharesMinted",
217 | "type": "uint256"
218 | },
219 | {
220 | "indexed": false,
221 | "name": "tokensDeposited",
222 | "type": "uint256"
223 | }
224 | ],
225 | "name": "Deposit",
226 | "type": "event"
227 | },
228 | {
229 | "anonymous": false,
230 | "inputs": [
231 | {
232 | "indexed": false,
233 | "name": "donor",
234 | "type": "address"
235 | },
236 | {
237 | "indexed": false,
238 | "name": "sharesBurned",
239 | "type": "uint256"
240 | }
241 | ],
242 | "name": "Withdraw",
243 | "type": "event"
244 | },
245 | {
246 | "anonymous": false,
247 | "inputs": [
248 | {
249 | "indexed": false,
250 | "name": "donor",
251 | "type": "address"
252 | },
253 | {
254 | "indexed": false,
255 | "name": "sharesBurned",
256 | "type": "uint256"
257 | },
258 | {
259 | "indexed": false,
260 | "name": "keeper",
261 | "type": "address"
262 | }
263 | ],
264 | "name": "KeeperWithdraw",
265 | "type": "event"
266 | },
267 | {
268 | "anonymous": false,
269 | "inputs": [
270 | {
271 | "indexed": false,
272 | "name": "donor",
273 | "type": "address"
274 | },
275 | {
276 | "indexed": false,
277 | "name": "addedKeepers",
278 | "type": "address[]"
279 | }
280 | ],
281 | "name": "AddKeepers",
282 | "type": "event"
283 | },
284 | {
285 | "anonymous": false,
286 | "inputs": [
287 | {
288 | "indexed": false,
289 | "name": "donor",
290 | "type": "address"
291 | },
292 | {
293 | "indexed": false,
294 | "name": "removedKeepers",
295 | "type": "address[]"
296 | }
297 | ],
298 | "name": "RemoveKeepers",
299 | "type": "event"
300 | },
301 | {
302 | "anonymous": false,
303 | "inputs": [
304 | {
305 | "indexed": false,
306 | "name": "sharesToMint",
307 | "type": "uint256"
308 | },
309 | {
310 | "indexed": false,
311 | "name": "recipient",
312 | "type": "address"
313 | },
314 | {
315 | "indexed": false,
316 | "name": "totalPoolShares",
317 | "type": "uint256"
318 | }
319 | ],
320 | "name": "SharesMinted",
321 | "type": "event"
322 | },
323 | {
324 | "anonymous": false,
325 | "inputs": [
326 | {
327 | "indexed": false,
328 | "name": "sharesToBurn",
329 | "type": "uint256"
330 | },
331 | {
332 | "indexed": false,
333 | "name": "recipient",
334 | "type": "address"
335 | },
336 | {
337 | "indexed": false,
338 | "name": "totalPoolShares",
339 | "type": "uint256"
340 | }
341 | ],
342 | "name": "SharesBurned",
343 | "type": "event"
344 | }
345 | ]
346 |
--------------------------------------------------------------------------------
/contracts/moloch/oz/ERC20.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.2;
2 |
3 | import "./IERC20.sol";
4 | import "./SafeMath.sol";
5 |
6 | /**
7 | * @title Standard ERC20 token
8 | *
9 | * @dev Implementation of the basic standard token.
10 | * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
11 | * Originally based on code by FirstBlood:
12 | * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
13 | *
14 | * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
15 | * all accounts just by listening to said events. Note that this isn't required by the specification, and other
16 | * compliant implementations may not do it.
17 | */
18 | contract ERC20 is IERC20 {
19 | using SafeMath for uint256;
20 |
21 | mapping (address => uint256) private _balances;
22 |
23 | mapping (address => mapping (address => uint256)) private _allowed;
24 |
25 | uint256 private _totalSupply;
26 |
27 | /**
28 | * @dev Total number of tokens in existence
29 | */
30 | function totalSupply() public view returns (uint256) {
31 | return _totalSupply;
32 | }
33 |
34 | /**
35 | * @dev Gets the balance of the specified address.
36 | * @param owner The address to query the balance of.
37 | * @return An uint256 representing the amount owned by the passed address.
38 | */
39 | function balanceOf(address owner) public view returns (uint256) {
40 | return _balances[owner];
41 | }
42 |
43 | /**
44 | * @dev Function to check the amount of tokens that an owner allowed to a spender.
45 | * @param owner address The address which owns the funds.
46 | * @param spender address The address which will spend the funds.
47 | * @return A uint256 specifying the amount of tokens still available for the spender.
48 | */
49 | function allowance(address owner, address spender) public view returns (uint256) {
50 | return _allowed[owner][spender];
51 | }
52 |
53 | /**
54 | * @dev Transfer token for a specified address
55 | * @param to The address to transfer to.
56 | * @param value The amount to be transferred.
57 | */
58 | function transfer(address to, uint256 value) public returns (bool) {
59 | _transfer(msg.sender, to, value);
60 | return true;
61 | }
62 |
63 | /**
64 | * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
65 | * Beware that changing an allowance with this method brings the risk that someone may use both the old
66 | * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
67 | * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
68 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
69 | * @param spender The address which will spend the funds.
70 | * @param value The amount of tokens to be spent.
71 | */
72 | function approve(address spender, uint256 value) public returns (bool) {
73 | _approve(msg.sender, spender, value);
74 | return true;
75 | }
76 |
77 | /**
78 | * @dev Transfer tokens from one address to another.
79 | * Note that while this function emits an Approval event, this is not required as per the specification,
80 | * and other compliant implementations may not emit the event.
81 | * @param from address The address which you want to send tokens from
82 | * @param to address The address which you want to transfer to
83 | * @param value uint256 the amount of tokens to be transferred
84 | */
85 | function transferFrom(address from, address to, uint256 value) public returns (bool) {
86 | _transfer(from, to, value);
87 | _approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
88 | return true;
89 | }
90 |
91 | /**
92 | * @dev Increase the amount of tokens that an owner allowed to a spender.
93 | * approve should be called when allowed_[_spender] == 0. To increment
94 | * allowed value is better to use this function to avoid 2 calls (and wait until
95 | * the first transaction is mined)
96 | * From MonolithDAO Token.sol
97 | * Emits an Approval event.
98 | * @param spender The address which will spend the funds.
99 | * @param addedValue The amount of tokens to increase the allowance by.
100 | */
101 | function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
102 | _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));
103 | return true;
104 | }
105 |
106 | /**
107 | * @dev Decrease the amount of tokens that an owner allowed to a spender.
108 | * approve should be called when allowed_[_spender] == 0. To decrement
109 | * allowed value is better to use this function to avoid 2 calls (and wait until
110 | * the first transaction is mined)
111 | * From MonolithDAO Token.sol
112 | * Emits an Approval event.
113 | * @param spender The address which will spend the funds.
114 | * @param subtractedValue The amount of tokens to decrease the allowance by.
115 | */
116 | function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
117 | _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));
118 | return true;
119 | }
120 |
121 | /**
122 | * @dev Transfer token for a specified addresses
123 | * @param from The address to transfer from.
124 | * @param to The address to transfer to.
125 | * @param value The amount to be transferred.
126 | */
127 | function _transfer(address from, address to, uint256 value) internal {
128 | require(to != address(0));
129 |
130 | _balances[from] = _balances[from].sub(value);
131 | _balances[to] = _balances[to].add(value);
132 | emit Transfer(from, to, value);
133 | }
134 |
135 | /**
136 | * @dev Internal function that mints an amount of the token and assigns it to
137 | * an account. This encapsulates the modification of balances such that the
138 | * proper events are emitted.
139 | * @param account The account that will receive the created tokens.
140 | * @param value The amount that will be created.
141 | */
142 | function _mint(address account, uint256 value) internal {
143 | require(account != address(0));
144 |
145 | _totalSupply = _totalSupply.add(value);
146 | _balances[account] = _balances[account].add(value);
147 | emit Transfer(address(0), account, value);
148 | }
149 |
150 | /**
151 | * @dev Internal function that burns an amount of the token of a given
152 | * account.
153 | * @param account The account whose tokens will be burnt.
154 | * @param value The amount that will be burnt.
155 | */
156 | function _burn(address account, uint256 value) internal {
157 | require(account != address(0));
158 |
159 | _totalSupply = _totalSupply.sub(value);
160 | _balances[account] = _balances[account].sub(value);
161 | emit Transfer(account, address(0), value);
162 | }
163 |
164 | /**
165 | * @dev Approve an address to spend another addresses' tokens.
166 | * @param owner The address that owns the tokens.
167 | * @param spender The address that will spend the tokens.
168 | * @param value The number of tokens that can be spent.
169 | */
170 | function _approve(address owner, address spender, uint256 value) internal {
171 | require(spender != address(0));
172 | require(owner != address(0));
173 |
174 | _allowed[owner][spender] = value;
175 | emit Approval(owner, spender, value);
176 | }
177 |
178 | /**
179 | * @dev Internal function that burns an amount of the token of a given
180 | * account, deducting from the sender's allowance for said account. Uses the
181 | * internal burn function.
182 | * Emits an Approval event (reflecting the reduced allowance).
183 | * @param account The account whose tokens will be burnt.
184 | * @param value The amount that will be burnt.
185 | */
186 | function _burnFrom(address account, uint256 value) internal {
187 | _burn(account, value);
188 | _approve(account, msg.sender, _allowed[account][msg.sender].sub(value));
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/src/views/NewMinion.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
19 | ABI Selector
20 | Raw Bytes
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
34 |
40 |
45 |
56 |
62 |
63 |
64 | {{ input.name }} (type: {{ input.type }})
65 |
66 |
71 |
72 |
77 |
78 |
79 | Submit
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
111 |
112 |
117 |
118 |
119 | Submit
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
268 |
--------------------------------------------------------------------------------
/contracts/moloch/tokens/ClaimsToken.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.5.2;
2 |
3 | import "../oz/SafeMath.sol";
4 | import "../oz/IERC20.sol";
5 | import "../oz/ERC20.sol";
6 |
7 | /**
8 | * @dev Optional functions from the ERC20 standard.
9 | */
10 | contract ERC20Detailed is IERC20 {
11 | string private _name;
12 | string private _symbol;
13 | uint8 private _decimals;
14 |
15 | /**
16 | * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of
17 | * these values are immutable: they can only be set once during
18 | * construction.
19 | */
20 | constructor (string memory name, string memory symbol, uint8 decimals) public {
21 | _name = name;
22 | _symbol = symbol;
23 | _decimals = decimals;
24 | }
25 |
26 | /**
27 | * @dev Returns the name of the token.
28 | */
29 | function name() public view returns (string memory) {
30 | return _name;
31 | }
32 |
33 | /**
34 | * @dev Returns the symbol of the token, usually a shorter version of the
35 | * name.
36 | */
37 | function symbol() public view returns (string memory) {
38 | return _symbol;
39 | }
40 |
41 | /**
42 | * @dev Returns the number of decimals used to get its user representation.
43 | * For example, if `decimals` equals `2`, a balance of `505` tokens should
44 | * be displayed to a user as `5,05` (`505 / 10 ** 2`).
45 | *
46 | * Tokens usually opt for a value of 18, imitating the relationship between
47 | * Ether and Wei.
48 | *
49 | * NOTE: This information is only used for _display_ purposes: it in
50 | * no way affects any of the arithmetic of the contract, including
51 | * {IERC20-balanceOf} and {IERC20-transfer}.
52 | */
53 | function decimals() public view returns (uint8) {
54 | return _decimals;
55 | }
56 | }
57 |
58 | interface IClaimsToken {
59 |
60 | /**
61 | * @dev This event emits when funds to be deposited are sent to the token contract
62 | * @param from contains the address of the sender of the received funds
63 | * @param fundsReceived contains the amount of funds received for distribution
64 | */
65 | event FundsReceived(address indexed from, uint256 fundsReceived);
66 |
67 | /**
68 | * @dev This event emits when distributed funds are withdrawn by a token holder.
69 | * @param by contains the address of the receiver of funds
70 | * @param fundsWithdrawn contains the amount of funds that were withdrawn
71 | */
72 | event FundsWithdrawn(address indexed by, uint256 fundsWithdrawn);
73 |
74 | /**
75 | * @dev Withdraws available funds for user.
76 | */
77 | function withdrawFunds() external payable;
78 |
79 | /**
80 | * @dev Returns the amount of funds a given address is able to withdraw currently.
81 | * @param _forAddress Address of ClaimsToken holder
82 | * @return A uint256 representing the available funds for a given account
83 | */
84 | function availableFunds(address _forAddress) external view returns (uint256);
85 |
86 | /**
87 | * @dev Get cumulative funds received by ClaimsToken.
88 | * @return A uint256 representing the total funds received by ClaimsToken
89 | */
90 | function totalReceivedFunds() external view returns (uint256);
91 | }
92 |
93 | contract ClaimsToken is IClaimsToken, ERC20, ERC20Detailed {
94 |
95 | using SafeMath for uint256;
96 |
97 | // cumulative funds received by this contract
98 | uint256 public receivedFunds;
99 | // cumulative funds received which were already processed for distribution - by user
100 | mapping (address => uint256) public processedFunds;
101 | // claimed but not yet withdrawn funds for a user
102 | mapping (address => uint256) public claimedFunds;
103 |
104 |
105 | constructor(address _owner)
106 | public
107 | ERC20Detailed("ClaimsToken", "CST", 18)
108 | {
109 | _mint(_owner, 10000 * (10 ** uint256(18)));
110 |
111 | receivedFunds = 0;
112 | }
113 |
114 | /**
115 | * @dev Transfer token to a specified address.
116 | * Claims funds for both parties, whereby the amount of tokens withdrawn
117 | * is inherited by the new token owner.
118 | * @param _to The address to transfer to
119 | * @param _value The amount to be transferred
120 | */
121 | function transfer(address _to, uint256 _value)
122 | public
123 | returns (bool)
124 | {
125 | _claimFunds(msg.sender);
126 | _claimFunds(_to);
127 |
128 | return super.transfer(_to, _value);
129 | }
130 |
131 |
132 | /**
133 | * @dev Transfer tokens from one address to another.
134 | * Claims funds for both parties, whereby the amount of tokens withdrawn
135 | * is inherited by the new token owner.
136 | * @param _from address The address which you want to send tokens from
137 | * @param _to address The address which you want to transfer to
138 | * @param _value uint256 the amount of tokens to be transferred
139 | */
140 | function transferFrom(address _from, address _to, uint256 _value)
141 | public
142 | returns (bool)
143 | {
144 | _claimFunds(_from);
145 | _claimFunds(_to);
146 |
147 | return super.transferFrom(_from, _to, _value);
148 | }
149 |
150 | /**
151 | * @dev Get cumulative funds received by ClaimsToken.
152 | * @return A uint256 representing the total funds received by ClaimsToken
153 | */
154 | function totalReceivedFunds()
155 | external
156 | view
157 | returns (uint256)
158 | {
159 | return receivedFunds;
160 | }
161 |
162 | /**
163 | * @dev Returns the amount of funds a given address is able to withdraw currently.
164 | * @param _forAddress Address of ClaimsToken holder
165 | * @return A uint256 representing the available funds for a given account
166 | */
167 | function availableFunds(address _forAddress)
168 | public
169 | view
170 | returns (uint256)
171 | {
172 | return _calcUnprocessedFunds(_forAddress).add(claimedFunds[_forAddress]);
173 | }
174 |
175 | /**
176 | * @dev Increments cumulative received funds by new received funds.
177 | * Called when ClaimsToken receives funds.
178 | * @param _value Amount of tokens / Ether received
179 | */
180 | function _registerFunds(uint256 _value)
181 | internal
182 | {
183 | receivedFunds = receivedFunds.add(_value);
184 | }
185 |
186 | /**
187 | * @dev Returns payout for a user which can be withdrawn or claimed.
188 | * @param _forAddress Address of ClaimsToken holder
189 | */
190 | function _calcUnprocessedFunds(address _forAddress)
191 | internal
192 | view
193 | returns (uint256)
194 | {
195 | uint256 newReceivedFunds = receivedFunds.sub(processedFunds[_forAddress]);
196 | return balanceOf(_forAddress).mul(newReceivedFunds).div(totalSupply());
197 | }
198 |
199 | /**
200 | * @dev Claims funds for a user.
201 | * @param _forAddress Address of ClaimsToken holder
202 | */
203 | function _claimFunds(address _forAddress) internal {
204 | uint256 unprocessedFunds = _calcUnprocessedFunds(_forAddress);
205 |
206 | processedFunds[_forAddress] = receivedFunds;
207 | claimedFunds[_forAddress] = claimedFunds[_forAddress].add(unprocessedFunds);
208 | }
209 |
210 | /**
211 | * @dev Sets claimed but not yet withdrawn funds to 0,
212 | * marks total received funds as processed and
213 | * returns the withdrawable amount for a user.
214 | * @return A uint256 representing the withdrawable funds
215 | */
216 | function _prepareWithdraw()
217 | internal
218 | returns (uint256)
219 | {
220 | uint256 withdrawableFunds = availableFunds(msg.sender);
221 |
222 | processedFunds[msg.sender] = receivedFunds;
223 | claimedFunds[msg.sender] = 0;
224 |
225 | return withdrawableFunds;
226 | }
227 | }
228 |
229 | contract ClaimsTokenERC20Extension is IClaimsToken, ClaimsToken {
230 |
231 | // token that ClaimsToken takes in custodianship
232 | IERC20 public fundsToken;
233 |
234 | modifier onlyFundsToken () {
235 | require(msg.sender == address(fundsToken), "UNAUTHORIZED_SENDER");
236 | _;
237 | }
238 |
239 | constructor(address _owner, IERC20 _fundsToken)
240 | public
241 | ClaimsToken(_owner)
242 | {
243 | require(address(_fundsToken) != address(0));
244 |
245 | fundsToken = _fundsToken;
246 | }
247 |
248 | /**
249 | * @dev Withdraws available funds for user.
250 | */
251 | function withdrawFunds()
252 | external
253 | payable
254 | {
255 | require(msg.value == 0, "");
256 |
257 | uint256 withdrawableFunds = _prepareWithdraw();
258 |
259 | require(fundsToken.transfer(msg.sender, withdrawableFunds), "TRANSFER_FAILED");
260 | }
261 |
262 | /**
263 | * @dev For ERC223.
264 | * Calls _registerFunds(), whereby total received funds (cumulative) gets updated.
265 | * @param _sender Sender of tokens
266 | * @param _value Amount of tokens
267 | */
268 | function tokenFallback(address _sender, uint256 _value, bytes memory)
269 | public
270 | onlyFundsToken()
271 | {
272 | if (_value > 0) {
273 | _registerFunds(_value);
274 | emit FundsReceived(_sender, _value);
275 | }
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/src/abi/certnft.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "stateMutability": "nonpayable",
5 | "type": "constructor"
6 | },
7 | {
8 | "anonymous": false,
9 | "inputs": [
10 | {
11 | "indexed": true,
12 | "internalType": "address",
13 | "name": "owner",
14 | "type": "address"
15 | },
16 | {
17 | "indexed": true,
18 | "internalType": "address",
19 | "name": "approved",
20 | "type": "address"
21 | },
22 | {
23 | "indexed": true,
24 | "internalType": "uint256",
25 | "name": "tokenId",
26 | "type": "uint256"
27 | }
28 | ],
29 | "name": "Approval",
30 | "type": "event"
31 | },
32 | {
33 | "anonymous": false,
34 | "inputs": [
35 | {
36 | "indexed": true,
37 | "internalType": "address",
38 | "name": "owner",
39 | "type": "address"
40 | },
41 | {
42 | "indexed": true,
43 | "internalType": "address",
44 | "name": "operator",
45 | "type": "address"
46 | },
47 | {
48 | "indexed": false,
49 | "internalType": "bool",
50 | "name": "approved",
51 | "type": "bool"
52 | }
53 | ],
54 | "name": "ApprovalForAll",
55 | "type": "event"
56 | },
57 | {
58 | "inputs": [
59 | {
60 | "internalType": "address",
61 | "name": "to",
62 | "type": "address"
63 | },
64 | {
65 | "internalType": "uint256",
66 | "name": "tokenId",
67 | "type": "uint256"
68 | }
69 | ],
70 | "name": "approve",
71 | "outputs": [],
72 | "stateMutability": "nonpayable",
73 | "type": "function"
74 | },
75 | {
76 | "inputs": [
77 | {
78 | "internalType": "address[]",
79 | "name": "players",
80 | "type": "address[]"
81 | },
82 | {
83 | "internalType": "string",
84 | "name": "tokenURI",
85 | "type": "string"
86 | }
87 | ],
88 | "name": "awardCerts",
89 | "outputs": [
90 | {
91 | "internalType": "bool",
92 | "name": "",
93 | "type": "bool"
94 | }
95 | ],
96 | "stateMutability": "nonpayable",
97 | "type": "function"
98 | },
99 | {
100 | "anonymous": false,
101 | "inputs": [
102 | {
103 | "indexed": true,
104 | "internalType": "address",
105 | "name": "previousOwner",
106 | "type": "address"
107 | },
108 | {
109 | "indexed": true,
110 | "internalType": "address",
111 | "name": "newOwner",
112 | "type": "address"
113 | }
114 | ],
115 | "name": "OwnershipTransferred",
116 | "type": "event"
117 | },
118 | {
119 | "inputs": [],
120 | "name": "renounceOwnership",
121 | "outputs": [],
122 | "stateMutability": "nonpayable",
123 | "type": "function"
124 | },
125 | {
126 | "inputs": [
127 | {
128 | "internalType": "address",
129 | "name": "_from",
130 | "type": "address"
131 | },
132 | {
133 | "internalType": "address",
134 | "name": "_to",
135 | "type": "address"
136 | },
137 | {
138 | "internalType": "bytes",
139 | "name": "_data",
140 | "type": "bytes"
141 | }
142 | ],
143 | "name": "safeTransferAllFrom",
144 | "outputs": [],
145 | "stateMutability": "nonpayable",
146 | "type": "function"
147 | },
148 | {
149 | "inputs": [
150 | {
151 | "internalType": "address",
152 | "name": "from",
153 | "type": "address"
154 | },
155 | {
156 | "internalType": "address",
157 | "name": "to",
158 | "type": "address"
159 | },
160 | {
161 | "internalType": "uint256",
162 | "name": "tokenId",
163 | "type": "uint256"
164 | }
165 | ],
166 | "name": "safeTransferFrom",
167 | "outputs": [],
168 | "stateMutability": "nonpayable",
169 | "type": "function"
170 | },
171 | {
172 | "inputs": [
173 | {
174 | "internalType": "address",
175 | "name": "from",
176 | "type": "address"
177 | },
178 | {
179 | "internalType": "address",
180 | "name": "to",
181 | "type": "address"
182 | },
183 | {
184 | "internalType": "uint256",
185 | "name": "tokenId",
186 | "type": "uint256"
187 | },
188 | {
189 | "internalType": "bytes",
190 | "name": "_data",
191 | "type": "bytes"
192 | }
193 | ],
194 | "name": "safeTransferFrom",
195 | "outputs": [],
196 | "stateMutability": "nonpayable",
197 | "type": "function"
198 | },
199 | {
200 | "inputs": [
201 | {
202 | "internalType": "address",
203 | "name": "operator",
204 | "type": "address"
205 | },
206 | {
207 | "internalType": "bool",
208 | "name": "approved",
209 | "type": "bool"
210 | }
211 | ],
212 | "name": "setApprovalForAll",
213 | "outputs": [],
214 | "stateMutability": "nonpayable",
215 | "type": "function"
216 | },
217 | {
218 | "anonymous": false,
219 | "inputs": [
220 | {
221 | "indexed": true,
222 | "internalType": "address",
223 | "name": "from",
224 | "type": "address"
225 | },
226 | {
227 | "indexed": true,
228 | "internalType": "address",
229 | "name": "to",
230 | "type": "address"
231 | },
232 | {
233 | "indexed": true,
234 | "internalType": "uint256",
235 | "name": "tokenId",
236 | "type": "uint256"
237 | }
238 | ],
239 | "name": "Transfer",
240 | "type": "event"
241 | },
242 | {
243 | "inputs": [
244 | {
245 | "internalType": "address",
246 | "name": "from",
247 | "type": "address"
248 | },
249 | {
250 | "internalType": "address",
251 | "name": "to",
252 | "type": "address"
253 | },
254 | {
255 | "internalType": "uint256",
256 | "name": "tokenId",
257 | "type": "uint256"
258 | }
259 | ],
260 | "name": "transferFrom",
261 | "outputs": [],
262 | "stateMutability": "nonpayable",
263 | "type": "function"
264 | },
265 | {
266 | "inputs": [
267 | {
268 | "internalType": "address",
269 | "name": "newOwner",
270 | "type": "address"
271 | }
272 | ],
273 | "name": "transferOwnership",
274 | "outputs": [],
275 | "stateMutability": "nonpayable",
276 | "type": "function"
277 | },
278 | {
279 | "inputs": [
280 | {
281 | "internalType": "address",
282 | "name": "owner",
283 | "type": "address"
284 | }
285 | ],
286 | "name": "balanceOf",
287 | "outputs": [
288 | {
289 | "internalType": "uint256",
290 | "name": "",
291 | "type": "uint256"
292 | }
293 | ],
294 | "stateMutability": "view",
295 | "type": "function"
296 | },
297 | {
298 | "inputs": [],
299 | "name": "baseURI",
300 | "outputs": [
301 | {
302 | "internalType": "string",
303 | "name": "",
304 | "type": "string"
305 | }
306 | ],
307 | "stateMutability": "view",
308 | "type": "function"
309 | },
310 | {
311 | "inputs": [
312 | {
313 | "internalType": "uint256",
314 | "name": "tokenId",
315 | "type": "uint256"
316 | }
317 | ],
318 | "name": "getApproved",
319 | "outputs": [
320 | {
321 | "internalType": "address",
322 | "name": "",
323 | "type": "address"
324 | }
325 | ],
326 | "stateMutability": "view",
327 | "type": "function"
328 | },
329 | {
330 | "inputs": [
331 | {
332 | "internalType": "address",
333 | "name": "owner",
334 | "type": "address"
335 | },
336 | {
337 | "internalType": "address",
338 | "name": "operator",
339 | "type": "address"
340 | }
341 | ],
342 | "name": "isApprovedForAll",
343 | "outputs": [
344 | {
345 | "internalType": "bool",
346 | "name": "",
347 | "type": "bool"
348 | }
349 | ],
350 | "stateMutability": "view",
351 | "type": "function"
352 | },
353 | {
354 | "inputs": [],
355 | "name": "name",
356 | "outputs": [
357 | {
358 | "internalType": "string",
359 | "name": "",
360 | "type": "string"
361 | }
362 | ],
363 | "stateMutability": "view",
364 | "type": "function"
365 | },
366 | {
367 | "inputs": [],
368 | "name": "owner",
369 | "outputs": [
370 | {
371 | "internalType": "address",
372 | "name": "",
373 | "type": "address"
374 | }
375 | ],
376 | "stateMutability": "view",
377 | "type": "function"
378 | },
379 | {
380 | "inputs": [
381 | {
382 | "internalType": "uint256",
383 | "name": "tokenId",
384 | "type": "uint256"
385 | }
386 | ],
387 | "name": "ownerOf",
388 | "outputs": [
389 | {
390 | "internalType": "address",
391 | "name": "",
392 | "type": "address"
393 | }
394 | ],
395 | "stateMutability": "view",
396 | "type": "function"
397 | },
398 | {
399 | "inputs": [
400 | {
401 | "internalType": "bytes4",
402 | "name": "interfaceId",
403 | "type": "bytes4"
404 | }
405 | ],
406 | "name": "supportsInterface",
407 | "outputs": [
408 | {
409 | "internalType": "bool",
410 | "name": "",
411 | "type": "bool"
412 | }
413 | ],
414 | "stateMutability": "view",
415 | "type": "function"
416 | },
417 | {
418 | "inputs": [],
419 | "name": "symbol",
420 | "outputs": [
421 | {
422 | "internalType": "string",
423 | "name": "",
424 | "type": "string"
425 | }
426 | ],
427 | "stateMutability": "view",
428 | "type": "function"
429 | },
430 | {
431 | "inputs": [
432 | {
433 | "internalType": "uint256",
434 | "name": "index",
435 | "type": "uint256"
436 | }
437 | ],
438 | "name": "tokenByIndex",
439 | "outputs": [
440 | {
441 | "internalType": "uint256",
442 | "name": "",
443 | "type": "uint256"
444 | }
445 | ],
446 | "stateMutability": "view",
447 | "type": "function"
448 | },
449 | {
450 | "inputs": [
451 | {
452 | "internalType": "address",
453 | "name": "owner",
454 | "type": "address"
455 | },
456 | {
457 | "internalType": "uint256",
458 | "name": "index",
459 | "type": "uint256"
460 | }
461 | ],
462 | "name": "tokenOfOwnerByIndex",
463 | "outputs": [
464 | {
465 | "internalType": "uint256",
466 | "name": "",
467 | "type": "uint256"
468 | }
469 | ],
470 | "stateMutability": "view",
471 | "type": "function"
472 | },
473 | {
474 | "inputs": [
475 | {
476 | "internalType": "uint256",
477 | "name": "tokenId",
478 | "type": "uint256"
479 | }
480 | ],
481 | "name": "tokenURI",
482 | "outputs": [
483 | {
484 | "internalType": "string",
485 | "name": "",
486 | "type": "string"
487 | }
488 | ],
489 | "stateMutability": "view",
490 | "type": "function"
491 | },
492 | {
493 | "inputs": [],
494 | "name": "totalSupply",
495 | "outputs": [
496 | {
497 | "internalType": "uint256",
498 | "name": "",
499 | "type": "uint256"
500 | }
501 | ],
502 | "stateMutability": "view",
503 | "type": "function"
504 | }
505 | ]
506 |
--------------------------------------------------------------------------------
/public/img/icons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.11, written by Peter Selinger 2001-2013
9 |
10 |
12 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/src/abi/minion_subdomain_registrar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "contract ENS",
6 | "name": "_ens",
7 | "type": "address"
8 | }
9 | ],
10 | "payable": false,
11 | "stateMutability": "nonpayable",
12 | "type": "constructor"
13 | },
14 | {
15 | "anonymous": false,
16 | "inputs": [
17 | {
18 | "indexed": true,
19 | "internalType": "bytes32",
20 | "name": "label",
21 | "type": "bytes32"
22 | },
23 | {
24 | "indexed": false,
25 | "internalType": "string",
26 | "name": "domain",
27 | "type": "string"
28 | },
29 | {
30 | "indexed": true,
31 | "internalType": "address",
32 | "name": "minion",
33 | "type": "address"
34 | }
35 | ],
36 | "name": "DomainConfigured",
37 | "type": "event"
38 | },
39 | {
40 | "anonymous": false,
41 | "inputs": [
42 | {
43 | "indexed": true,
44 | "internalType": "bytes32",
45 | "name": "label",
46 | "type": "bytes32"
47 | },
48 | {
49 | "indexed": false,
50 | "internalType": "string",
51 | "name": "name",
52 | "type": "string"
53 | }
54 | ],
55 | "name": "DomainTransferred",
56 | "type": "event"
57 | },
58 | {
59 | "anonymous": false,
60 | "inputs": [
61 | {
62 | "indexed": true,
63 | "internalType": "bytes32",
64 | "name": "label",
65 | "type": "bytes32"
66 | }
67 | ],
68 | "name": "DomainUnlisted",
69 | "type": "event"
70 | },
71 | {
72 | "anonymous": false,
73 | "inputs": [
74 | {
75 | "indexed": true,
76 | "internalType": "bytes32",
77 | "name": "label",
78 | "type": "bytes32"
79 | },
80 | {
81 | "indexed": false,
82 | "internalType": "string",
83 | "name": "subdomain",
84 | "type": "string"
85 | },
86 | {
87 | "indexed": true,
88 | "internalType": "address",
89 | "name": "owner",
90 | "type": "address"
91 | }
92 | ],
93 | "name": "NewRegistration",
94 | "type": "event"
95 | },
96 | {
97 | "anonymous": false,
98 | "inputs": [
99 | {
100 | "indexed": true,
101 | "internalType": "bytes32",
102 | "name": "label",
103 | "type": "bytes32"
104 | },
105 | {
106 | "indexed": true,
107 | "internalType": "address",
108 | "name": "oldOwner",
109 | "type": "address"
110 | },
111 | {
112 | "indexed": true,
113 | "internalType": "address",
114 | "name": "newOwner",
115 | "type": "address"
116 | }
117 | ],
118 | "name": "OwnerChanged",
119 | "type": "event"
120 | },
121 | {
122 | "anonymous": false,
123 | "inputs": [
124 | {
125 | "indexed": true,
126 | "internalType": "bytes32",
127 | "name": "label",
128 | "type": "bytes32"
129 | },
130 | {
131 | "indexed": false,
132 | "internalType": "address",
133 | "name": "addr",
134 | "type": "address"
135 | }
136 | ],
137 | "name": "TransferAddressSet",
138 | "type": "event"
139 | },
140 | {
141 | "constant": true,
142 | "inputs": [],
143 | "name": "TLD_NODE",
144 | "outputs": [
145 | {
146 | "internalType": "bytes32",
147 | "name": "",
148 | "type": "bytes32"
149 | }
150 | ],
151 | "payable": false,
152 | "stateMutability": "view",
153 | "type": "function"
154 | },
155 | {
156 | "constant": false,
157 | "inputs": [
158 | {
159 | "internalType": "string",
160 | "name": "name",
161 | "type": "string"
162 | },
163 | {
164 | "internalType": "address",
165 | "name": "minion",
166 | "type": "address"
167 | }
168 | ],
169 | "name": "configureDomain",
170 | "outputs": [],
171 | "payable": false,
172 | "stateMutability": "nonpayable",
173 | "type": "function"
174 | },
175 | {
176 | "constant": false,
177 | "inputs": [
178 | {
179 | "internalType": "string",
180 | "name": "name",
181 | "type": "string"
182 | },
183 | {
184 | "internalType": "address",
185 | "name": "minion",
186 | "type": "address"
187 | },
188 | {
189 | "internalType": "address",
190 | "name": "_owner",
191 | "type": "address"
192 | }
193 | ],
194 | "name": "configureDomainFor",
195 | "outputs": [],
196 | "payable": false,
197 | "stateMutability": "nonpayable",
198 | "type": "function"
199 | },
200 | {
201 | "constant": false,
202 | "inputs": [
203 | {
204 | "internalType": "bytes32",
205 | "name": "label",
206 | "type": "bytes32"
207 | },
208 | {
209 | "internalType": "string",
210 | "name": "subdomain",
211 | "type": "string"
212 | },
213 | {
214 | "internalType": "address",
215 | "name": "resolver",
216 | "type": "address"
217 | }
218 | ],
219 | "name": "deregister",
220 | "outputs": [],
221 | "payable": false,
222 | "stateMutability": "nonpayable",
223 | "type": "function"
224 | },
225 | {
226 | "constant": true,
227 | "inputs": [],
228 | "name": "ens",
229 | "outputs": [
230 | {
231 | "internalType": "contract ENS",
232 | "name": "",
233 | "type": "address"
234 | }
235 | ],
236 | "payable": false,
237 | "stateMutability": "view",
238 | "type": "function"
239 | },
240 | {
241 | "constant": false,
242 | "inputs": [
243 | {
244 | "internalType": "string",
245 | "name": "name",
246 | "type": "string"
247 | }
248 | ],
249 | "name": "migrate",
250 | "outputs": [],
251 | "payable": false,
252 | "stateMutability": "nonpayable",
253 | "type": "function"
254 | },
255 | {
256 | "constant": true,
257 | "inputs": [],
258 | "name": "migration",
259 | "outputs": [
260 | {
261 | "internalType": "address",
262 | "name": "",
263 | "type": "address"
264 | }
265 | ],
266 | "payable": false,
267 | "stateMutability": "view",
268 | "type": "function"
269 | },
270 | {
271 | "constant": true,
272 | "inputs": [
273 | {
274 | "internalType": "bytes32",
275 | "name": "label",
276 | "type": "bytes32"
277 | }
278 | ],
279 | "name": "owner",
280 | "outputs": [
281 | {
282 | "internalType": "address",
283 | "name": "",
284 | "type": "address"
285 | }
286 | ],
287 | "payable": false,
288 | "stateMutability": "view",
289 | "type": "function"
290 | },
291 | {
292 | "constant": false,
293 | "inputs": [
294 | {
295 | "internalType": "bytes32",
296 | "name": "label",
297 | "type": "bytes32"
298 | },
299 | {
300 | "internalType": "string",
301 | "name": "subdomain",
302 | "type": "string"
303 | },
304 | {
305 | "internalType": "address",
306 | "name": "_subdomainOwner",
307 | "type": "address"
308 | },
309 | {
310 | "internalType": "address",
311 | "name": "resolver",
312 | "type": "address"
313 | }
314 | ],
315 | "name": "register",
316 | "outputs": [],
317 | "payable": false,
318 | "stateMutability": "nonpayable",
319 | "type": "function"
320 | },
321 | {
322 | "constant": true,
323 | "inputs": [],
324 | "name": "registrar",
325 | "outputs": [
326 | {
327 | "internalType": "address",
328 | "name": "",
329 | "type": "address"
330 | }
331 | ],
332 | "payable": false,
333 | "stateMutability": "view",
334 | "type": "function"
335 | },
336 | {
337 | "constant": true,
338 | "inputs": [],
339 | "name": "registrarOwner",
340 | "outputs": [
341 | {
342 | "internalType": "address",
343 | "name": "",
344 | "type": "address"
345 | }
346 | ],
347 | "payable": false,
348 | "stateMutability": "view",
349 | "type": "function"
350 | },
351 | {
352 | "constant": false,
353 | "inputs": [
354 | {
355 | "internalType": "address",
356 | "name": "_migration",
357 | "type": "address"
358 | }
359 | ],
360 | "name": "setMigrationAddress",
361 | "outputs": [],
362 | "payable": false,
363 | "stateMutability": "nonpayable",
364 | "type": "function"
365 | },
366 | {
367 | "constant": false,
368 | "inputs": [
369 | {
370 | "internalType": "string",
371 | "name": "name",
372 | "type": "string"
373 | },
374 | {
375 | "internalType": "address",
376 | "name": "resolver",
377 | "type": "address"
378 | }
379 | ],
380 | "name": "setResolver",
381 | "outputs": [],
382 | "payable": false,
383 | "stateMutability": "nonpayable",
384 | "type": "function"
385 | },
386 | {
387 | "constant": false,
388 | "inputs": [],
389 | "name": "stop",
390 | "outputs": [],
391 | "payable": false,
392 | "stateMutability": "nonpayable",
393 | "type": "function"
394 | },
395 | {
396 | "constant": true,
397 | "inputs": [],
398 | "name": "stopped",
399 | "outputs": [
400 | {
401 | "internalType": "bool",
402 | "name": "",
403 | "type": "bool"
404 | }
405 | ],
406 | "payable": false,
407 | "stateMutability": "view",
408 | "type": "function"
409 | },
410 | {
411 | "constant": false,
412 | "inputs": [
413 | {
414 | "internalType": "string",
415 | "name": "name",
416 | "type": "string"
417 | },
418 | {
419 | "internalType": "address",
420 | "name": "newOwner",
421 | "type": "address"
422 | }
423 | ],
424 | "name": "transfer",
425 | "outputs": [],
426 | "payable": false,
427 | "stateMutability": "nonpayable",
428 | "type": "function"
429 | },
430 | {
431 | "constant": false,
432 | "inputs": [
433 | {
434 | "internalType": "address",
435 | "name": "newOwner",
436 | "type": "address"
437 | }
438 | ],
439 | "name": "transferOwnership",
440 | "outputs": [],
441 | "payable": false,
442 | "stateMutability": "nonpayable",
443 | "type": "function"
444 | },
445 | {
446 | "constant": false,
447 | "inputs": [
448 | {
449 | "internalType": "string",
450 | "name": "name",
451 | "type": "string"
452 | }
453 | ],
454 | "name": "unlistDomain",
455 | "outputs": [],
456 | "payable": false,
457 | "stateMutability": "nonpayable",
458 | "type": "function"
459 | }
460 | ]
461 |
--------------------------------------------------------------------------------
/src/abi/moloch_v1.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "constant": true,
4 | "inputs": [],
5 | "name": "processingReward",
6 | "outputs": [
7 | {
8 | "name": "",
9 | "type": "uint256"
10 | }
11 | ],
12 | "payable": false,
13 | "stateMutability": "view",
14 | "type": "function"
15 | },
16 | {
17 | "constant": true,
18 | "inputs": [
19 | {
20 | "name": "memberAddress",
21 | "type": "address"
22 | },
23 | {
24 | "name": "proposalIndex",
25 | "type": "uint256"
26 | }
27 | ],
28 | "name": "getMemberProposalVote",
29 | "outputs": [
30 | {
31 | "name": "",
32 | "type": "uint8"
33 | }
34 | ],
35 | "payable": false,
36 | "stateMutability": "view",
37 | "type": "function"
38 | },
39 | {
40 | "constant": true,
41 | "inputs": [],
42 | "name": "getCurrentPeriod",
43 | "outputs": [
44 | {
45 | "name": "",
46 | "type": "uint256"
47 | }
48 | ],
49 | "payable": false,
50 | "stateMutability": "view",
51 | "type": "function"
52 | },
53 | {
54 | "constant": true,
55 | "inputs": [
56 | {
57 | "name": "",
58 | "type": "address"
59 | }
60 | ],
61 | "name": "members",
62 | "outputs": [
63 | {
64 | "name": "delegateKey",
65 | "type": "address"
66 | },
67 | {
68 | "name": "shares",
69 | "type": "uint256"
70 | },
71 | {
72 | "name": "exists",
73 | "type": "bool"
74 | },
75 | {
76 | "name": "highestIndexYesVote",
77 | "type": "uint256"
78 | }
79 | ],
80 | "payable": false,
81 | "stateMutability": "view",
82 | "type": "function"
83 | },
84 | {
85 | "constant": true,
86 | "inputs": [],
87 | "name": "totalSharesRequested",
88 | "outputs": [
89 | {
90 | "name": "",
91 | "type": "uint256"
92 | }
93 | ],
94 | "payable": false,
95 | "stateMutability": "view",
96 | "type": "function"
97 | },
98 | {
99 | "constant": false,
100 | "inputs": [
101 | {
102 | "name": "newDelegateKey",
103 | "type": "address"
104 | }
105 | ],
106 | "name": "updateDelegateKey",
107 | "outputs": [],
108 | "payable": false,
109 | "stateMutability": "nonpayable",
110 | "type": "function"
111 | },
112 | {
113 | "constant": true,
114 | "inputs": [],
115 | "name": "totalShares",
116 | "outputs": [
117 | {
118 | "name": "",
119 | "type": "uint256"
120 | }
121 | ],
122 | "payable": false,
123 | "stateMutability": "view",
124 | "type": "function"
125 | },
126 | {
127 | "constant": true,
128 | "inputs": [
129 | {
130 | "name": "",
131 | "type": "uint256"
132 | }
133 | ],
134 | "name": "proposalQueue",
135 | "outputs": [
136 | {
137 | "name": "proposer",
138 | "type": "address"
139 | },
140 | {
141 | "name": "applicant",
142 | "type": "address"
143 | },
144 | {
145 | "name": "sharesRequested",
146 | "type": "uint256"
147 | },
148 | {
149 | "name": "startingPeriod",
150 | "type": "uint256"
151 | },
152 | {
153 | "name": "yesVotes",
154 | "type": "uint256"
155 | },
156 | {
157 | "name": "noVotes",
158 | "type": "uint256"
159 | },
160 | {
161 | "name": "processed",
162 | "type": "bool"
163 | },
164 | {
165 | "name": "didPass",
166 | "type": "bool"
167 | },
168 | {
169 | "name": "aborted",
170 | "type": "bool"
171 | },
172 | {
173 | "name": "tokenTribute",
174 | "type": "uint256"
175 | },
176 | {
177 | "name": "details",
178 | "type": "string"
179 | },
180 | {
181 | "name": "maxTotalSharesAtYesVote",
182 | "type": "uint256"
183 | }
184 | ],
185 | "payable": false,
186 | "stateMutability": "view",
187 | "type": "function"
188 | },
189 | {
190 | "constant": true,
191 | "inputs": [
192 | {
193 | "name": "",
194 | "type": "address"
195 | }
196 | ],
197 | "name": "memberAddressByDelegateKey",
198 | "outputs": [
199 | {
200 | "name": "",
201 | "type": "address"
202 | }
203 | ],
204 | "payable": false,
205 | "stateMutability": "view",
206 | "type": "function"
207 | },
208 | {
209 | "constant": true,
210 | "inputs": [],
211 | "name": "gracePeriodLength",
212 | "outputs": [
213 | {
214 | "name": "",
215 | "type": "uint256"
216 | }
217 | ],
218 | "payable": false,
219 | "stateMutability": "view",
220 | "type": "function"
221 | },
222 | {
223 | "constant": true,
224 | "inputs": [],
225 | "name": "abortWindow",
226 | "outputs": [
227 | {
228 | "name": "",
229 | "type": "uint256"
230 | }
231 | ],
232 | "payable": false,
233 | "stateMutability": "view",
234 | "type": "function"
235 | },
236 | {
237 | "constant": true,
238 | "inputs": [],
239 | "name": "getProposalQueueLength",
240 | "outputs": [
241 | {
242 | "name": "",
243 | "type": "uint256"
244 | }
245 | ],
246 | "payable": false,
247 | "stateMutability": "view",
248 | "type": "function"
249 | },
250 | {
251 | "constant": true,
252 | "inputs": [],
253 | "name": "summoningTime",
254 | "outputs": [
255 | {
256 | "name": "",
257 | "type": "uint256"
258 | }
259 | ],
260 | "payable": false,
261 | "stateMutability": "view",
262 | "type": "function"
263 | },
264 | {
265 | "constant": true,
266 | "inputs": [],
267 | "name": "votingPeriodLength",
268 | "outputs": [
269 | {
270 | "name": "",
271 | "type": "uint256"
272 | }
273 | ],
274 | "payable": false,
275 | "stateMutability": "view",
276 | "type": "function"
277 | },
278 | {
279 | "constant": false,
280 | "inputs": [
281 | {
282 | "name": "sharesToBurn",
283 | "type": "uint256"
284 | }
285 | ],
286 | "name": "ragequit",
287 | "outputs": [],
288 | "payable": false,
289 | "stateMutability": "nonpayable",
290 | "type": "function"
291 | },
292 | {
293 | "constant": true,
294 | "inputs": [],
295 | "name": "proposalDeposit",
296 | "outputs": [
297 | {
298 | "name": "",
299 | "type": "uint256"
300 | }
301 | ],
302 | "payable": false,
303 | "stateMutability": "view",
304 | "type": "function"
305 | },
306 | {
307 | "constant": true,
308 | "inputs": [
309 | {
310 | "name": "startingPeriod",
311 | "type": "uint256"
312 | }
313 | ],
314 | "name": "hasVotingPeriodExpired",
315 | "outputs": [
316 | {
317 | "name": "",
318 | "type": "bool"
319 | }
320 | ],
321 | "payable": false,
322 | "stateMutability": "view",
323 | "type": "function"
324 | },
325 | {
326 | "constant": false,
327 | "inputs": [
328 | {
329 | "name": "applicant",
330 | "type": "address"
331 | },
332 | {
333 | "name": "tokenTribute",
334 | "type": "uint256"
335 | },
336 | {
337 | "name": "sharesRequested",
338 | "type": "uint256"
339 | },
340 | {
341 | "name": "details",
342 | "type": "string"
343 | }
344 | ],
345 | "name": "submitProposal",
346 | "outputs": [],
347 | "payable": false,
348 | "stateMutability": "nonpayable",
349 | "type": "function"
350 | },
351 | {
352 | "constant": false,
353 | "inputs": [
354 | {
355 | "name": "proposalIndex",
356 | "type": "uint256"
357 | },
358 | {
359 | "name": "uintVote",
360 | "type": "uint8"
361 | }
362 | ],
363 | "name": "submitVote",
364 | "outputs": [],
365 | "payable": false,
366 | "stateMutability": "nonpayable",
367 | "type": "function"
368 | },
369 | {
370 | "constant": true,
371 | "inputs": [
372 | {
373 | "name": "highestIndexYesVote",
374 | "type": "uint256"
375 | }
376 | ],
377 | "name": "canRagequit",
378 | "outputs": [
379 | {
380 | "name": "",
381 | "type": "bool"
382 | }
383 | ],
384 | "payable": false,
385 | "stateMutability": "view",
386 | "type": "function"
387 | },
388 | {
389 | "constant": true,
390 | "inputs": [],
391 | "name": "guildBank",
392 | "outputs": [
393 | {
394 | "name": "",
395 | "type": "address"
396 | }
397 | ],
398 | "payable": false,
399 | "stateMutability": "view",
400 | "type": "function"
401 | },
402 | {
403 | "constant": true,
404 | "inputs": [],
405 | "name": "dilutionBound",
406 | "outputs": [
407 | {
408 | "name": "",
409 | "type": "uint256"
410 | }
411 | ],
412 | "payable": false,
413 | "stateMutability": "view",
414 | "type": "function"
415 | },
416 | {
417 | "constant": true,
418 | "inputs": [],
419 | "name": "periodDuration",
420 | "outputs": [
421 | {
422 | "name": "",
423 | "type": "uint256"
424 | }
425 | ],
426 | "payable": false,
427 | "stateMutability": "view",
428 | "type": "function"
429 | },
430 | {
431 | "constant": true,
432 | "inputs": [],
433 | "name": "approvedToken",
434 | "outputs": [
435 | {
436 | "name": "",
437 | "type": "address"
438 | }
439 | ],
440 | "payable": false,
441 | "stateMutability": "view",
442 | "type": "function"
443 | },
444 | {
445 | "constant": false,
446 | "inputs": [
447 | {
448 | "name": "proposalIndex",
449 | "type": "uint256"
450 | }
451 | ],
452 | "name": "abort",
453 | "outputs": [],
454 | "payable": false,
455 | "stateMutability": "nonpayable",
456 | "type": "function"
457 | },
458 | {
459 | "constant": false,
460 | "inputs": [
461 | {
462 | "name": "proposalIndex",
463 | "type": "uint256"
464 | }
465 | ],
466 | "name": "processProposal",
467 | "outputs": [],
468 | "payable": false,
469 | "stateMutability": "nonpayable",
470 | "type": "function"
471 | },
472 | {
473 | "inputs": [
474 | {
475 | "name": "summoner",
476 | "type": "address"
477 | },
478 | {
479 | "name": "_approvedToken",
480 | "type": "address"
481 | },
482 | {
483 | "name": "_periodDuration",
484 | "type": "uint256"
485 | },
486 | {
487 | "name": "_votingPeriodLength",
488 | "type": "uint256"
489 | },
490 | {
491 | "name": "_gracePeriodLength",
492 | "type": "uint256"
493 | },
494 | {
495 | "name": "_abortWindow",
496 | "type": "uint256"
497 | },
498 | {
499 | "name": "_proposalDeposit",
500 | "type": "uint256"
501 | },
502 | {
503 | "name": "_dilutionBound",
504 | "type": "uint256"
505 | },
506 | {
507 | "name": "_processingReward",
508 | "type": "uint256"
509 | }
510 | ],
511 | "payable": false,
512 | "stateMutability": "nonpayable",
513 | "type": "constructor"
514 | },
515 | {
516 | "anonymous": false,
517 | "inputs": [
518 | {
519 | "indexed": false,
520 | "name": "proposalIndex",
521 | "type": "uint256"
522 | },
523 | {
524 | "indexed": true,
525 | "name": "delegateKey",
526 | "type": "address"
527 | },
528 | {
529 | "indexed": true,
530 | "name": "memberAddress",
531 | "type": "address"
532 | },
533 | {
534 | "indexed": true,
535 | "name": "applicant",
536 | "type": "address"
537 | },
538 | {
539 | "indexed": false,
540 | "name": "tokenTribute",
541 | "type": "uint256"
542 | },
543 | {
544 | "indexed": false,
545 | "name": "sharesRequested",
546 | "type": "uint256"
547 | }
548 | ],
549 | "name": "SubmitProposal",
550 | "type": "event"
551 | },
552 | {
553 | "anonymous": false,
554 | "inputs": [
555 | {
556 | "indexed": true,
557 | "name": "proposalIndex",
558 | "type": "uint256"
559 | },
560 | {
561 | "indexed": true,
562 | "name": "delegateKey",
563 | "type": "address"
564 | },
565 | {
566 | "indexed": true,
567 | "name": "memberAddress",
568 | "type": "address"
569 | },
570 | {
571 | "indexed": false,
572 | "name": "uintVote",
573 | "type": "uint8"
574 | }
575 | ],
576 | "name": "SubmitVote",
577 | "type": "event"
578 | },
579 | {
580 | "anonymous": false,
581 | "inputs": [
582 | {
583 | "indexed": true,
584 | "name": "proposalIndex",
585 | "type": "uint256"
586 | },
587 | {
588 | "indexed": true,
589 | "name": "applicant",
590 | "type": "address"
591 | },
592 | {
593 | "indexed": true,
594 | "name": "memberAddress",
595 | "type": "address"
596 | },
597 | {
598 | "indexed": false,
599 | "name": "tokenTribute",
600 | "type": "uint256"
601 | },
602 | {
603 | "indexed": false,
604 | "name": "sharesRequested",
605 | "type": "uint256"
606 | },
607 | {
608 | "indexed": false,
609 | "name": "didPass",
610 | "type": "bool"
611 | }
612 | ],
613 | "name": "ProcessProposal",
614 | "type": "event"
615 | },
616 | {
617 | "anonymous": false,
618 | "inputs": [
619 | {
620 | "indexed": true,
621 | "name": "memberAddress",
622 | "type": "address"
623 | },
624 | {
625 | "indexed": false,
626 | "name": "sharesToBurn",
627 | "type": "uint256"
628 | }
629 | ],
630 | "name": "Ragequit",
631 | "type": "event"
632 | },
633 | {
634 | "anonymous": false,
635 | "inputs": [
636 | {
637 | "indexed": true,
638 | "name": "proposalIndex",
639 | "type": "uint256"
640 | },
641 | {
642 | "indexed": false,
643 | "name": "applicantAddress",
644 | "type": "address"
645 | }
646 | ],
647 | "name": "Abort",
648 | "type": "event"
649 | },
650 | {
651 | "anonymous": false,
652 | "inputs": [
653 | {
654 | "indexed": true,
655 | "name": "memberAddress",
656 | "type": "address"
657 | },
658 | {
659 | "indexed": false,
660 | "name": "newDelegateKey",
661 | "type": "address"
662 | }
663 | ],
664 | "name": "UpdateDelegateKey",
665 | "type": "event"
666 | },
667 | {
668 | "anonymous": false,
669 | "inputs": [
670 | {
671 | "indexed": true,
672 | "name": "summoner",
673 | "type": "address"
674 | },
675 | {
676 | "indexed": false,
677 | "name": "shares",
678 | "type": "uint256"
679 | }
680 | ],
681 | "name": "SummonComplete",
682 | "type": "event"
683 | }
684 | ]
685 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Minion Navigation
6 |
7 |
8 | mdi-view-dashboard
9 |
10 |
11 | Current Proposals
12 |
13 |
14 |
15 |
16 | mdi-view-dashboard
17 |
18 |
19 | Submit New Proposals
20 |
21 |
22 |
23 |
24 | mdi-settings
25 |
26 |
27 | About
28 |
29 |
30 |
31 | Forged Tools
32 |
33 |
34 | mdi-settings
35 |
36 |
37 | ENS
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | Minion
46 |
47 | {{ user }}
48 |
49 |
50 |
51 |
52 |
63 |
64 |
65 |
66 |
67 |
68 | Minion Details
69 | proposer: {{ details.proposer }}
70 | target: {{ details.to }}
71 |
72 | method: {{ details.method }}
73 |
74 |
75 | params:
76 |
77 |
82 | {{ item.name }}: {{ item.value }}
83 |
84 | data: {{ details.data }}
85 |
86 |
87 | Close
90 |
91 |
92 |
93 |
94 |
95 |
96 | © 2020
97 |
98 | Minion {{ minionAddr.substring(0, 6) }}...
99 |
100 | Moloch {{ molochAddr.substring(0, 6) }}...
101 |
102 |
103 |
104 |
105 |
106 |
107 |
494 |
--------------------------------------------------------------------------------
/src/abi/ens_registrar.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | {
5 | "internalType": "contract ENS",
6 | "name": "_ens",
7 | "type": "address"
8 | },
9 | {
10 | "internalType": "bytes32",
11 | "name": "_baseNode",
12 | "type": "bytes32"
13 | }
14 | ],
15 | "payable": false,
16 | "stateMutability": "nonpayable",
17 | "type": "constructor"
18 | },
19 | {
20 | "anonymous": false,
21 | "inputs": [
22 | {
23 | "indexed": true,
24 | "internalType": "address",
25 | "name": "owner",
26 | "type": "address"
27 | },
28 | {
29 | "indexed": true,
30 | "internalType": "address",
31 | "name": "approved",
32 | "type": "address"
33 | },
34 | {
35 | "indexed": true,
36 | "internalType": "uint256",
37 | "name": "tokenId",
38 | "type": "uint256"
39 | }
40 | ],
41 | "name": "Approval",
42 | "type": "event"
43 | },
44 | {
45 | "anonymous": false,
46 | "inputs": [
47 | {
48 | "indexed": true,
49 | "internalType": "address",
50 | "name": "owner",
51 | "type": "address"
52 | },
53 | {
54 | "indexed": true,
55 | "internalType": "address",
56 | "name": "operator",
57 | "type": "address"
58 | },
59 | {
60 | "indexed": false,
61 | "internalType": "bool",
62 | "name": "approved",
63 | "type": "bool"
64 | }
65 | ],
66 | "name": "ApprovalForAll",
67 | "type": "event"
68 | },
69 | {
70 | "anonymous": false,
71 | "inputs": [
72 | {
73 | "indexed": true,
74 | "internalType": "address",
75 | "name": "controller",
76 | "type": "address"
77 | }
78 | ],
79 | "name": "ControllerAdded",
80 | "type": "event"
81 | },
82 | {
83 | "anonymous": false,
84 | "inputs": [
85 | {
86 | "indexed": true,
87 | "internalType": "address",
88 | "name": "controller",
89 | "type": "address"
90 | }
91 | ],
92 | "name": "ControllerRemoved",
93 | "type": "event"
94 | },
95 | {
96 | "anonymous": false,
97 | "inputs": [
98 | {
99 | "indexed": true,
100 | "internalType": "uint256",
101 | "name": "id",
102 | "type": "uint256"
103 | },
104 | {
105 | "indexed": true,
106 | "internalType": "address",
107 | "name": "owner",
108 | "type": "address"
109 | },
110 | {
111 | "indexed": false,
112 | "internalType": "uint256",
113 | "name": "expires",
114 | "type": "uint256"
115 | }
116 | ],
117 | "name": "NameMigrated",
118 | "type": "event"
119 | },
120 | {
121 | "anonymous": false,
122 | "inputs": [
123 | {
124 | "indexed": true,
125 | "internalType": "uint256",
126 | "name": "id",
127 | "type": "uint256"
128 | },
129 | {
130 | "indexed": true,
131 | "internalType": "address",
132 | "name": "owner",
133 | "type": "address"
134 | },
135 | {
136 | "indexed": false,
137 | "internalType": "uint256",
138 | "name": "expires",
139 | "type": "uint256"
140 | }
141 | ],
142 | "name": "NameRegistered",
143 | "type": "event"
144 | },
145 | {
146 | "anonymous": false,
147 | "inputs": [
148 | {
149 | "indexed": true,
150 | "internalType": "uint256",
151 | "name": "id",
152 | "type": "uint256"
153 | },
154 | {
155 | "indexed": false,
156 | "internalType": "uint256",
157 | "name": "expires",
158 | "type": "uint256"
159 | }
160 | ],
161 | "name": "NameRenewed",
162 | "type": "event"
163 | },
164 | {
165 | "anonymous": false,
166 | "inputs": [
167 | {
168 | "indexed": true,
169 | "internalType": "address",
170 | "name": "previousOwner",
171 | "type": "address"
172 | },
173 | {
174 | "indexed": true,
175 | "internalType": "address",
176 | "name": "newOwner",
177 | "type": "address"
178 | }
179 | ],
180 | "name": "OwnershipTransferred",
181 | "type": "event"
182 | },
183 | {
184 | "anonymous": false,
185 | "inputs": [
186 | {
187 | "indexed": true,
188 | "internalType": "address",
189 | "name": "from",
190 | "type": "address"
191 | },
192 | {
193 | "indexed": true,
194 | "internalType": "address",
195 | "name": "to",
196 | "type": "address"
197 | },
198 | {
199 | "indexed": true,
200 | "internalType": "uint256",
201 | "name": "tokenId",
202 | "type": "uint256"
203 | }
204 | ],
205 | "name": "Transfer",
206 | "type": "event"
207 | },
208 | {
209 | "constant": true,
210 | "inputs": [],
211 | "name": "GRACE_PERIOD",
212 | "outputs": [
213 | {
214 | "internalType": "uint256",
215 | "name": "",
216 | "type": "uint256"
217 | }
218 | ],
219 | "payable": false,
220 | "stateMutability": "view",
221 | "type": "function"
222 | },
223 | {
224 | "constant": false,
225 | "inputs": [
226 | {
227 | "internalType": "address",
228 | "name": "controller",
229 | "type": "address"
230 | }
231 | ],
232 | "name": "addController",
233 | "outputs": [],
234 | "payable": false,
235 | "stateMutability": "nonpayable",
236 | "type": "function"
237 | },
238 | {
239 | "constant": false,
240 | "inputs": [
241 | {
242 | "internalType": "address",
243 | "name": "to",
244 | "type": "address"
245 | },
246 | {
247 | "internalType": "uint256",
248 | "name": "tokenId",
249 | "type": "uint256"
250 | }
251 | ],
252 | "name": "approve",
253 | "outputs": [],
254 | "payable": false,
255 | "stateMutability": "nonpayable",
256 | "type": "function"
257 | },
258 | {
259 | "constant": true,
260 | "inputs": [
261 | {
262 | "internalType": "uint256",
263 | "name": "id",
264 | "type": "uint256"
265 | }
266 | ],
267 | "name": "available",
268 | "outputs": [
269 | {
270 | "internalType": "bool",
271 | "name": "",
272 | "type": "bool"
273 | }
274 | ],
275 | "payable": false,
276 | "stateMutability": "view",
277 | "type": "function"
278 | },
279 | {
280 | "constant": true,
281 | "inputs": [
282 | {
283 | "internalType": "address",
284 | "name": "owner",
285 | "type": "address"
286 | }
287 | ],
288 | "name": "balanceOf",
289 | "outputs": [
290 | {
291 | "internalType": "uint256",
292 | "name": "",
293 | "type": "uint256"
294 | }
295 | ],
296 | "payable": false,
297 | "stateMutability": "view",
298 | "type": "function"
299 | },
300 | {
301 | "constant": true,
302 | "inputs": [],
303 | "name": "baseNode",
304 | "outputs": [
305 | {
306 | "internalType": "bytes32",
307 | "name": "",
308 | "type": "bytes32"
309 | }
310 | ],
311 | "payable": false,
312 | "stateMutability": "view",
313 | "type": "function"
314 | },
315 | {
316 | "constant": true,
317 | "inputs": [
318 | {
319 | "internalType": "address",
320 | "name": "",
321 | "type": "address"
322 | }
323 | ],
324 | "name": "controllers",
325 | "outputs": [
326 | {
327 | "internalType": "bool",
328 | "name": "",
329 | "type": "bool"
330 | }
331 | ],
332 | "payable": false,
333 | "stateMutability": "view",
334 | "type": "function"
335 | },
336 | {
337 | "constant": true,
338 | "inputs": [],
339 | "name": "ens",
340 | "outputs": [
341 | {
342 | "internalType": "contract ENS",
343 | "name": "",
344 | "type": "address"
345 | }
346 | ],
347 | "payable": false,
348 | "stateMutability": "view",
349 | "type": "function"
350 | },
351 | {
352 | "constant": true,
353 | "inputs": [
354 | {
355 | "internalType": "uint256",
356 | "name": "tokenId",
357 | "type": "uint256"
358 | }
359 | ],
360 | "name": "getApproved",
361 | "outputs": [
362 | {
363 | "internalType": "address",
364 | "name": "",
365 | "type": "address"
366 | }
367 | ],
368 | "payable": false,
369 | "stateMutability": "view",
370 | "type": "function"
371 | },
372 | {
373 | "constant": true,
374 | "inputs": [
375 | {
376 | "internalType": "address",
377 | "name": "owner",
378 | "type": "address"
379 | },
380 | {
381 | "internalType": "address",
382 | "name": "operator",
383 | "type": "address"
384 | }
385 | ],
386 | "name": "isApprovedForAll",
387 | "outputs": [
388 | {
389 | "internalType": "bool",
390 | "name": "",
391 | "type": "bool"
392 | }
393 | ],
394 | "payable": false,
395 | "stateMutability": "view",
396 | "type": "function"
397 | },
398 | {
399 | "constant": true,
400 | "inputs": [],
401 | "name": "isOwner",
402 | "outputs": [
403 | {
404 | "internalType": "bool",
405 | "name": "",
406 | "type": "bool"
407 | }
408 | ],
409 | "payable": false,
410 | "stateMutability": "view",
411 | "type": "function"
412 | },
413 | {
414 | "constant": true,
415 | "inputs": [
416 | {
417 | "internalType": "uint256",
418 | "name": "id",
419 | "type": "uint256"
420 | }
421 | ],
422 | "name": "nameExpires",
423 | "outputs": [
424 | {
425 | "internalType": "uint256",
426 | "name": "",
427 | "type": "uint256"
428 | }
429 | ],
430 | "payable": false,
431 | "stateMutability": "view",
432 | "type": "function"
433 | },
434 | {
435 | "constant": true,
436 | "inputs": [],
437 | "name": "owner",
438 | "outputs": [
439 | {
440 | "internalType": "address",
441 | "name": "",
442 | "type": "address"
443 | }
444 | ],
445 | "payable": false,
446 | "stateMutability": "view",
447 | "type": "function"
448 | },
449 | {
450 | "constant": true,
451 | "inputs": [
452 | {
453 | "internalType": "uint256",
454 | "name": "tokenId",
455 | "type": "uint256"
456 | }
457 | ],
458 | "name": "ownerOf",
459 | "outputs": [
460 | {
461 | "internalType": "address",
462 | "name": "",
463 | "type": "address"
464 | }
465 | ],
466 | "payable": false,
467 | "stateMutability": "view",
468 | "type": "function"
469 | },
470 | {
471 | "constant": false,
472 | "inputs": [
473 | {
474 | "internalType": "uint256",
475 | "name": "id",
476 | "type": "uint256"
477 | },
478 | {
479 | "internalType": "address",
480 | "name": "owner",
481 | "type": "address"
482 | }
483 | ],
484 | "name": "reclaim",
485 | "outputs": [],
486 | "payable": false,
487 | "stateMutability": "nonpayable",
488 | "type": "function"
489 | },
490 | {
491 | "constant": false,
492 | "inputs": [
493 | {
494 | "internalType": "uint256",
495 | "name": "id",
496 | "type": "uint256"
497 | },
498 | {
499 | "internalType": "address",
500 | "name": "owner",
501 | "type": "address"
502 | },
503 | {
504 | "internalType": "uint256",
505 | "name": "duration",
506 | "type": "uint256"
507 | }
508 | ],
509 | "name": "register",
510 | "outputs": [
511 | {
512 | "internalType": "uint256",
513 | "name": "",
514 | "type": "uint256"
515 | }
516 | ],
517 | "payable": false,
518 | "stateMutability": "nonpayable",
519 | "type": "function"
520 | },
521 | {
522 | "constant": false,
523 | "inputs": [
524 | {
525 | "internalType": "uint256",
526 | "name": "id",
527 | "type": "uint256"
528 | },
529 | {
530 | "internalType": "address",
531 | "name": "owner",
532 | "type": "address"
533 | },
534 | {
535 | "internalType": "uint256",
536 | "name": "duration",
537 | "type": "uint256"
538 | }
539 | ],
540 | "name": "registerOnly",
541 | "outputs": [
542 | {
543 | "internalType": "uint256",
544 | "name": "",
545 | "type": "uint256"
546 | }
547 | ],
548 | "payable": false,
549 | "stateMutability": "nonpayable",
550 | "type": "function"
551 | },
552 | {
553 | "constant": false,
554 | "inputs": [
555 | {
556 | "internalType": "address",
557 | "name": "controller",
558 | "type": "address"
559 | }
560 | ],
561 | "name": "removeController",
562 | "outputs": [],
563 | "payable": false,
564 | "stateMutability": "nonpayable",
565 | "type": "function"
566 | },
567 | {
568 | "constant": false,
569 | "inputs": [
570 | {
571 | "internalType": "uint256",
572 | "name": "id",
573 | "type": "uint256"
574 | },
575 | {
576 | "internalType": "uint256",
577 | "name": "duration",
578 | "type": "uint256"
579 | }
580 | ],
581 | "name": "renew",
582 | "outputs": [
583 | {
584 | "internalType": "uint256",
585 | "name": "",
586 | "type": "uint256"
587 | }
588 | ],
589 | "payable": false,
590 | "stateMutability": "nonpayable",
591 | "type": "function"
592 | },
593 | {
594 | "constant": false,
595 | "inputs": [],
596 | "name": "renounceOwnership",
597 | "outputs": [],
598 | "payable": false,
599 | "stateMutability": "nonpayable",
600 | "type": "function"
601 | },
602 | {
603 | "constant": false,
604 | "inputs": [
605 | {
606 | "internalType": "address",
607 | "name": "from",
608 | "type": "address"
609 | },
610 | {
611 | "internalType": "address",
612 | "name": "to",
613 | "type": "address"
614 | },
615 | {
616 | "internalType": "uint256",
617 | "name": "tokenId",
618 | "type": "uint256"
619 | }
620 | ],
621 | "name": "safeTransferFrom",
622 | "outputs": [],
623 | "payable": false,
624 | "stateMutability": "nonpayable",
625 | "type": "function"
626 | },
627 | {
628 | "constant": false,
629 | "inputs": [
630 | {
631 | "internalType": "address",
632 | "name": "from",
633 | "type": "address"
634 | },
635 | {
636 | "internalType": "address",
637 | "name": "to",
638 | "type": "address"
639 | },
640 | {
641 | "internalType": "uint256",
642 | "name": "tokenId",
643 | "type": "uint256"
644 | },
645 | {
646 | "internalType": "bytes",
647 | "name": "_data",
648 | "type": "bytes"
649 | }
650 | ],
651 | "name": "safeTransferFrom",
652 | "outputs": [],
653 | "payable": false,
654 | "stateMutability": "nonpayable",
655 | "type": "function"
656 | },
657 | {
658 | "constant": false,
659 | "inputs": [
660 | {
661 | "internalType": "address",
662 | "name": "to",
663 | "type": "address"
664 | },
665 | {
666 | "internalType": "bool",
667 | "name": "approved",
668 | "type": "bool"
669 | }
670 | ],
671 | "name": "setApprovalForAll",
672 | "outputs": [],
673 | "payable": false,
674 | "stateMutability": "nonpayable",
675 | "type": "function"
676 | },
677 | {
678 | "constant": false,
679 | "inputs": [
680 | {
681 | "internalType": "address",
682 | "name": "resolver",
683 | "type": "address"
684 | }
685 | ],
686 | "name": "setResolver",
687 | "outputs": [],
688 | "payable": false,
689 | "stateMutability": "nonpayable",
690 | "type": "function"
691 | },
692 | {
693 | "constant": true,
694 | "inputs": [
695 | {
696 | "internalType": "bytes4",
697 | "name": "interfaceID",
698 | "type": "bytes4"
699 | }
700 | ],
701 | "name": "supportsInterface",
702 | "outputs": [
703 | {
704 | "internalType": "bool",
705 | "name": "",
706 | "type": "bool"
707 | }
708 | ],
709 | "payable": false,
710 | "stateMutability": "view",
711 | "type": "function"
712 | },
713 | {
714 | "constant": false,
715 | "inputs": [
716 | {
717 | "internalType": "address",
718 | "name": "from",
719 | "type": "address"
720 | },
721 | {
722 | "internalType": "address",
723 | "name": "to",
724 | "type": "address"
725 | },
726 | {
727 | "internalType": "uint256",
728 | "name": "tokenId",
729 | "type": "uint256"
730 | }
731 | ],
732 | "name": "transferFrom",
733 | "outputs": [],
734 | "payable": false,
735 | "stateMutability": "nonpayable",
736 | "type": "function"
737 | },
738 | {
739 | "constant": false,
740 | "inputs": [
741 | {
742 | "internalType": "address",
743 | "name": "newOwner",
744 | "type": "address"
745 | }
746 | ],
747 | "name": "transferOwnership",
748 | "outputs": [],
749 | "payable": false,
750 | "stateMutability": "nonpayable",
751 | "type": "function"
752 | }
753 | ]
754 |
--------------------------------------------------------------------------------
/tests/contracts/minion_integration.spec.ts:
--------------------------------------------------------------------------------
1 | import { waffle } from "@nomiclabs/buidler";
2 | import chai from "chai";
3 | import { ethers } from "ethers";
4 | import { deployContract, solidity } from "ethereum-waffle";
5 |
6 | import MinionArtifact from "../../build/artifacts/Minion.json";
7 | import MolochArtifact from "../../build/artifacts/Moloch.json";
8 | import TokenArtifact from "../../build/artifacts/Token.json";
9 | import TargetMockArtifact from "../../build/artifacts/TargetMock.json";
10 | import RevertingMolochArtifact from "../../build/artifacts/RevertingMoloch.json";
11 | import { Minion } from "../../build/types/Minion";
12 | import { Moloch } from "../../build/types/Moloch";
13 | import { Token } from "../../build/types/Token";
14 | import { TargetMock } from "../../build/types/TargetMock";
15 | import { RevertingMoloch } from "../../build/types/RevertingMoloch";
16 |
17 | import { Action, Proposal } from "./utils/types";
18 | import Constants from "./utils/constants";
19 | import Utils from "./utils/utils";
20 |
21 | chai.use(solidity);
22 | const { expect } = chai;
23 |
24 | describe("Minion integration", () => {
25 | const provider = waffle.provider;
26 | const [wallet, eoa] = provider.getWallets();
27 |
28 | let minion: Minion;
29 | let moloch: Moloch;
30 | let token: Token;
31 | let target: TargetMock;
32 |
33 | beforeEach(async () => {
34 | token = (await deployContract(wallet, TokenArtifact, [
35 | Constants.MaxUint256
36 | ])) as Token;
37 |
38 | moloch = (await deployContract(
39 | wallet,
40 | MolochArtifact,
41 | [
42 | wallet.address,
43 | [token.address],
44 | Constants.molochConfig.PERIOD_DURATION_IN_SECONDS,
45 | Constants.molochConfig.VOTING_DURATON_IN_PERIODS,
46 | Constants.molochConfig.GRACE_DURATON_IN_PERIODS,
47 | Constants.molochConfig.PROPOSAL_DEPOSIT,
48 | Constants.molochConfig.DILUTION_BOUND,
49 | Constants.molochConfig.PROCESSING_REWARD
50 | ],
51 | { gasLimit: 9500000 }
52 | )) as Moloch;
53 |
54 | minion = (await deployContract(wallet, MinionArtifact, [
55 | moloch.address
56 | ])) as Minion;
57 |
58 | target = (await deployContract(wallet, TargetMockArtifact)) as TargetMock;
59 | await token.approve(moloch.address, Constants.MaxUint256);
60 | });
61 |
62 | it("deploys correctly", async () => {
63 | expect(minion.address).to.not.eq(Constants.AddressZero);
64 | expect(await minion.moloch()).to.eq(moloch.address);
65 | expect(await minion.molochApprovedToken()).to.eq(token.address);
66 | expect(await minion.MINION_ACTION_DETAILS()).to.eq(
67 | Constants.MINION_ACTION_DETAILS
68 | );
69 | });
70 |
71 | describe("proposeAction", () => {
72 | describe("success cases", () => {
73 | let action: Action;
74 | let proposal: Proposal;
75 |
76 | beforeEach(async () => {
77 | action = {
78 | to: target.address,
79 | value: ethers.utils.parseEther("1"),
80 | data: ethers.utils.hexlify(ethers.utils.randomBytes(50)),
81 | description: "foo",
82 | proposalId: 0,
83 | queueIndex: 0
84 | };
85 | proposal = {
86 | applicant: minion.address,
87 | proposer: minion.address,
88 | sharesRequested: 0,
89 | lootRequested: 0,
90 | tributeOffered: 0,
91 | tributeToken: token.address,
92 | paymentRequested: 0,
93 | paymentToken: token.address,
94 | details: Utils.encodeDetailsString(action.description)
95 | };
96 | await minion.proposeAction(
97 | action.to,
98 | action.value,
99 | action.data,
100 | action.description
101 | );
102 | });
103 |
104 | it("stores the correct action", async () => {
105 | const storedAction = await minion.actions(action.proposalId);
106 | expect(storedAction.to).to.equal(action.to);
107 | expect(storedAction.value).to.equal(action.value);
108 | expect(storedAction.data).to.equal(action.data);
109 | expect(storedAction.proposer).to.equal(wallet.address);
110 | expect(storedAction.executed).to.equal(false);
111 | });
112 |
113 | it("submits the correct proposal to parent moloch", async () => {
114 | const storedProposal = await moloch.proposals(action.proposalId);
115 | const proposalFlags = await moloch.getProposalFlags(action.proposalId);
116 | expect(proposalFlags).to.deep.equal([
117 | false,
118 | false,
119 | false,
120 | false,
121 | false,
122 | false
123 | ]);
124 | expect(storedProposal.applicant).to.equal(proposal.applicant);
125 | expect(storedProposal.proposer).to.equal(proposal.proposer);
126 | expect(storedProposal.sponsor).to.equal(Constants.AddressZero);
127 | expect(storedProposal.sharesRequested).to.equal(
128 | proposal.sharesRequested
129 | );
130 | expect(storedProposal.lootRequested).to.equal(proposal.lootRequested);
131 | expect(storedProposal.tributeOffered).to.equal(proposal.tributeOffered);
132 | expect(storedProposal.tributeToken).to.equal(proposal.tributeToken);
133 | expect(storedProposal.paymentRequested).to.equal(
134 | proposal.paymentRequested
135 | );
136 | expect(storedProposal.paymentToken).to.equal(proposal.paymentToken);
137 | expect(storedProposal.details).to.equal(proposal.details);
138 | });
139 |
140 | it("emits expected events", async () => {
141 | const proposalId = 1;
142 | await expect(
143 | minion.proposeAction(
144 | action.to,
145 | action.value,
146 | action.data,
147 | action.description
148 | )
149 | )
150 | .to.emit(minion, "ActionProposed")
151 | .withArgs(proposalId, wallet.address)
152 | .to.emit(moloch, "SubmitProposal")
153 | .withArgs(
154 | proposal.applicant,
155 | proposal.sharesRequested,
156 | proposal.lootRequested,
157 | proposal.tributeOffered,
158 | proposal.tributeToken,
159 | proposal.paymentRequested,
160 | proposal.paymentToken,
161 | proposal.details,
162 | [false, false, false, false, false],
163 | proposalId,
164 | minion.address,
165 | Constants.AddressZero
166 | );
167 | });
168 | });
169 |
170 | describe("failure cases", () => {
171 | it("reverts proposal to zero address", async () => {
172 | const badAction = {
173 | to: Constants.AddressZero,
174 | value: ethers.utils.parseEther("1"),
175 | data: ethers.utils.hexlify(ethers.utils.randomBytes(50)),
176 | description: "foo"
177 | };
178 | await expect(
179 | minion.proposeAction(
180 | badAction.to,
181 | badAction.value,
182 | badAction.data,
183 | badAction.description
184 | )
185 | ).to.be.revertedWith(Constants.revertStrings.INVALID_PROP_TARGET);
186 | });
187 |
188 | it("reverts if moloch proposal fails", async () => {
189 | const action = {
190 | to: target.address,
191 | value: ethers.utils.parseEther("1"),
192 | data: ethers.utils.hexlify(ethers.utils.randomBytes(50)),
193 | description: "foo"
194 | };
195 | const revertingMoloch = (await deployContract(
196 | wallet,
197 | RevertingMolochArtifact
198 | )) as Moloch;
199 | const revertingMinion = (await deployContract(wallet, MinionArtifact, [
200 | revertingMoloch.address
201 | ])) as Minion;
202 | await expect(
203 | revertingMinion.proposeAction(
204 | action.to,
205 | action.value,
206 | action.data,
207 | action.description
208 | )
209 | ).to.be.revertedWith(Constants.revertStrings.none);
210 | });
211 | });
212 | });
213 |
214 | describe("executeAction", () => {
215 | describe("success cases", () => {
216 | let action1: Action, action2: Action, emptyAddressAction: Action;
217 |
218 | beforeEach(async () => {
219 | await Utils.incProposalCount(moloch, 1);
220 | action1 = {
221 | to: target.address,
222 | value: ethers.utils.parseEther("0"),
223 | data: "0x",
224 | description: "foo",
225 | proposalId: 1,
226 | queueIndex: 0
227 | };
228 | action2 = {
229 | to: target.address,
230 | value: ethers.utils.parseEther("1"),
231 | data: ethers.utils.hexlify(ethers.utils.randomBytes(50)),
232 | description: "foo",
233 | proposalId: 2,
234 | queueIndex: 1
235 | };
236 | emptyAddressAction = {
237 | to: eoa.address,
238 | value: ethers.utils.parseEther("0"),
239 | data: ethers.utils.hexlify(ethers.utils.randomBytes(50)),
240 | description: "foo",
241 | proposalId: 3,
242 | queueIndex: 2
243 | };
244 | await Utils.proposeAndPass(minion, moloch, action1);
245 | await Utils.proposeAndPass(minion, moloch, action2);
246 | await Utils.proposeAndPass(minion, moloch, emptyAddressAction);
247 | });
248 |
249 | it("executes a passed proposal", async () => {
250 | await expect(minion.executeAction(action1.proposalId))
251 | .to.emit(minion, "ActionExecuted")
252 | .withArgs(action1.proposalId, wallet.address)
253 | .to.emit(target, "Called")
254 | .withArgs(minion.address, action1.value, action1.data);
255 | expect((await minion.actions(action1.proposalId)).executed).to.be.true;
256 | });
257 |
258 | it("executes proposal with data and value", async () => {
259 | await wallet.sendTransaction({
260 | to: minion.address,
261 | value: action2.value
262 | });
263 | await expect(minion.executeAction(action2.proposalId))
264 | .to.emit(minion, "ActionExecuted")
265 | .withArgs(action2.proposalId, wallet.address)
266 | .to.emit(target, "Called")
267 | .withArgs(minion.address, action2.value, action2.data);
268 | expect((await minion.actions(action2.proposalId)).executed).to.be.true;
269 | expect(await provider.getBalance(target.address)).to.equal(
270 | action2.value
271 | );
272 | });
273 |
274 | it("executes actions in any order", async () => {
275 | await wallet.sendTransaction({
276 | to: minion.address,
277 | value: action2.value
278 | });
279 | await expect(minion.executeAction(action2.proposalId))
280 | .to.emit(minion, "ActionExecuted")
281 | .withArgs(action2.proposalId, wallet.address)
282 | .to.emit(target, "Called")
283 | .withArgs(minion.address, action2.value, action2.data);
284 | expect((await minion.actions(action2.proposalId)).executed).to.be.true;
285 |
286 | await expect(minion.executeAction(action1.proposalId))
287 | .to.emit(minion, "ActionExecuted")
288 | .withArgs(action1.proposalId, wallet.address)
289 | .to.emit(target, "Called")
290 | .withArgs(minion.address, action1.value, action1.data);
291 | expect((await minion.actions(action1.proposalId)).executed).to.be.true;
292 | });
293 |
294 | // *** Be aware that calls to empty addresses should succeed,
295 | // even if they contain data.
296 | it("SUCCESSFULLY sends data to an EMPTY address", async () => {
297 | await minion.executeAction(emptyAddressAction.proposalId);
298 | });
299 | });
300 |
301 | describe("failure cases", () => {
302 | let unpassedAction: Action,
303 | valueAction: Action,
304 | actionToMoloch: Action,
305 | executedAction: Action,
306 | failingCallAction: Action;
307 |
308 | beforeEach(async () => {
309 | unpassedAction = {
310 | to: target.address,
311 | value: ethers.utils.parseEther("0"),
312 | data: "0x",
313 | description: "foo",
314 | proposalId: 0,
315 | queueIndex: 0
316 | };
317 | valueAction = {
318 | to: target.address,
319 | value: ethers.utils.parseEther("1"),
320 | data: "0x",
321 | description: "foo",
322 | proposalId: 1,
323 | queueIndex: 0
324 | };
325 | actionToMoloch = {
326 | to: moloch.address,
327 | value: ethers.utils.parseEther("0"),
328 | data: "0x",
329 | description: "foo",
330 | proposalId: 2,
331 | queueIndex: 1
332 | };
333 | executedAction = {
334 | to: target.address,
335 | value: ethers.utils.parseEther("0"),
336 | data: "0x",
337 | description: "foo",
338 | proposalId: 3,
339 | queueIndex: 2
340 | };
341 | failingCallAction = {
342 | to: target.address,
343 | value: ethers.utils.parseEther("0"),
344 | data: new ethers.utils.Interface(TargetMockArtifact.abi).functions
345 | .fail.sighash,
346 | description: "foo",
347 | proposalId: 4,
348 | queueIndex: 3
349 | };
350 |
351 | // these executions need to stay in order to line up with the
352 | // proposalIds and queueIndices above. Sorry..
353 | await minion.proposeAction(
354 | unpassedAction.to,
355 | unpassedAction.value,
356 | unpassedAction.data,
357 | unpassedAction.description
358 | );
359 | await Utils.proposeAndPass(minion, moloch, valueAction);
360 | await Utils.proposeAndPass(minion, moloch, actionToMoloch);
361 | await Utils.proposeAndPass(minion, moloch, executedAction);
362 | await Utils.proposeAndPass(minion, moloch, failingCallAction);
363 |
364 | // execute the "executed action"
365 | await minion.executeAction(executedAction.proposalId);
366 | });
367 |
368 | it("reverts if insufficient eth", async () => {
369 | await expect(
370 | minion.executeAction(valueAction.proposalId)
371 | ).to.be.revertedWith(Constants.revertStrings.NO_ETH);
372 | });
373 |
374 | it("reverts on un-passed proposal", async () => {
375 | await expect(
376 | minion.executeAction(unpassedAction.proposalId)
377 | ).to.be.revertedWith(Constants.revertStrings.NOT_PASSED);
378 | });
379 |
380 | it("reverts action to moloch", async () => {
381 | await expect(
382 | minion.executeAction(actionToMoloch.proposalId)
383 | ).to.be.revertedWith(Constants.revertStrings.INVALID_EXEC_TARGET);
384 | });
385 |
386 | it("reverts a previously executed action", async () => {
387 | await expect(
388 | minion.executeAction(executedAction.proposalId)
389 | ).to.be.revertedWith(Constants.revertStrings.IS_EXECUTED);
390 | });
391 |
392 | it("reverts a proposal created by another source", async () => {
393 | // submit a proposal directly to the moloch, not through the minion
394 | await moloch.submitProposal(
395 | minion.address,
396 | 0,
397 | 0,
398 | 0,
399 | token.address,
400 | 0,
401 | token.address,
402 | ""
403 | );
404 | const proposalId = (await moloch.proposalCount()).sub(1).toNumber();
405 | const falseAction: Action = {
406 | to: target.address,
407 | value: ethers.utils.parseEther("0"),
408 | data: "0x",
409 | description: "foo",
410 | proposalId: proposalId,
411 | queueIndex: proposalId - 1
412 | };
413 | await Utils.passProposal(moloch, falseAction);
414 | await expect(
415 | minion.executeAction(falseAction.proposalId)
416 | ).to.be.revertedWith(Constants.revertStrings.INVALID_EXEC_ID);
417 | });
418 |
419 | it("fails if action call reverts", async () => {
420 | await expect(
421 | minion.executeAction(failingCallAction.proposalId)
422 | ).to.be.revertedWith(Constants.revertStrings.CALL_FAIL);
423 | });
424 | });
425 | });
426 |
427 | // TODO: Add an interface to withdrawBalances?
428 | describe("doWithdraw", () => {
429 | it("withdraws funds from parent moloch", async () => {
430 | const amount = ethers.utils.parseEther("1");
431 | await token.transfer(moloch.address, amount);
432 |
433 | // add tokens to guild bank balance
434 | await moloch.submitProposal(
435 | wallet.address,
436 | 0,
437 | 0,
438 | amount,
439 | token.address,
440 | 0,
441 | token.address,
442 | ""
443 | );
444 | // pay minion
445 | await moloch.submitProposal(
446 | minion.address,
447 | 0,
448 | 0,
449 | 0,
450 | token.address,
451 | amount,
452 | token.address,
453 | ""
454 | );
455 |
456 | // pass and process both proposals
457 | const fillGuildBankAction = {
458 | to: "",
459 | value: new ethers.utils.BigNumber(0),
460 | data: "0x",
461 | description: "",
462 | proposalId: 0,
463 | queueIndex: 0
464 | };
465 | const payMinionAction = {
466 | to: "",
467 | value: new ethers.utils.BigNumber(0),
468 | data: "0x",
469 | description: "",
470 | proposalId: 1,
471 | queueIndex: 1
472 | };
473 | await Utils.passProposal(moloch, fillGuildBankAction);
474 | await Utils.passProposal(moloch, payMinionAction);
475 |
476 | // withdraw minion balance
477 | await minion.doWithdraw(token.address, amount);
478 | });
479 | });
480 | });
481 |
--------------------------------------------------------------------------------
/src/abi/uniswap_v2_router.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "name": "WETH",
5 | "outputs": [
6 | {
7 | "internalType": "address",
8 | "name": "",
9 | "type": "address"
10 | }
11 | ],
12 | "stateMutability": "pure",
13 | "type": "function"
14 | },
15 | {
16 | "inputs": [
17 | {
18 | "internalType": "address",
19 | "name": "tokenA",
20 | "type": "address"
21 | },
22 | {
23 | "internalType": "address",
24 | "name": "tokenB",
25 | "type": "address"
26 | },
27 | {
28 | "internalType": "uint256",
29 | "name": "amountADesired",
30 | "type": "uint256"
31 | },
32 | {
33 | "internalType": "uint256",
34 | "name": "amountBDesired",
35 | "type": "uint256"
36 | },
37 | {
38 | "internalType": "uint256",
39 | "name": "amountAMin",
40 | "type": "uint256"
41 | },
42 | {
43 | "internalType": "uint256",
44 | "name": "amountBMin",
45 | "type": "uint256"
46 | },
47 | {
48 | "internalType": "address",
49 | "name": "to",
50 | "type": "address"
51 | },
52 | {
53 | "internalType": "uint256",
54 | "name": "deadline",
55 | "type": "uint256"
56 | }
57 | ],
58 | "name": "addLiquidity",
59 | "outputs": [
60 | {
61 | "internalType": "uint256",
62 | "name": "amountA",
63 | "type": "uint256"
64 | },
65 | {
66 | "internalType": "uint256",
67 | "name": "amountB",
68 | "type": "uint256"
69 | },
70 | {
71 | "internalType": "uint256",
72 | "name": "liquidity",
73 | "type": "uint256"
74 | }
75 | ],
76 | "stateMutability": "nonpayable",
77 | "type": "function"
78 | },
79 | {
80 | "inputs": [
81 | {
82 | "internalType": "address",
83 | "name": "token",
84 | "type": "address"
85 | },
86 | {
87 | "internalType": "uint256",
88 | "name": "amountTokenDesired",
89 | "type": "uint256"
90 | },
91 | {
92 | "internalType": "uint256",
93 | "name": "amountTokenMin",
94 | "type": "uint256"
95 | },
96 | {
97 | "internalType": "uint256",
98 | "name": "amountETHMin",
99 | "type": "uint256"
100 | },
101 | {
102 | "internalType": "address",
103 | "name": "to",
104 | "type": "address"
105 | },
106 | {
107 | "internalType": "uint256",
108 | "name": "deadline",
109 | "type": "uint256"
110 | }
111 | ],
112 | "name": "addLiquidityETH",
113 | "outputs": [
114 | {
115 | "internalType": "uint256",
116 | "name": "amountToken",
117 | "type": "uint256"
118 | },
119 | {
120 | "internalType": "uint256",
121 | "name": "amountETH",
122 | "type": "uint256"
123 | },
124 | {
125 | "internalType": "uint256",
126 | "name": "liquidity",
127 | "type": "uint256"
128 | }
129 | ],
130 | "stateMutability": "payable",
131 | "type": "function"
132 | },
133 | {
134 | "inputs": [],
135 | "name": "factory",
136 | "outputs": [
137 | {
138 | "internalType": "address",
139 | "name": "",
140 | "type": "address"
141 | }
142 | ],
143 | "stateMutability": "pure",
144 | "type": "function"
145 | },
146 | {
147 | "inputs": [
148 | {
149 | "internalType": "uint256",
150 | "name": "amountOut",
151 | "type": "uint256"
152 | },
153 | {
154 | "internalType": "uint256",
155 | "name": "reserveIn",
156 | "type": "uint256"
157 | },
158 | {
159 | "internalType": "uint256",
160 | "name": "reserveOut",
161 | "type": "uint256"
162 | }
163 | ],
164 | "name": "getAmountIn",
165 | "outputs": [
166 | {
167 | "internalType": "uint256",
168 | "name": "amountIn",
169 | "type": "uint256"
170 | }
171 | ],
172 | "stateMutability": "pure",
173 | "type": "function"
174 | },
175 | {
176 | "inputs": [
177 | {
178 | "internalType": "uint256",
179 | "name": "amountIn",
180 | "type": "uint256"
181 | },
182 | {
183 | "internalType": "uint256",
184 | "name": "reserveIn",
185 | "type": "uint256"
186 | },
187 | {
188 | "internalType": "uint256",
189 | "name": "reserveOut",
190 | "type": "uint256"
191 | }
192 | ],
193 | "name": "getAmountOut",
194 | "outputs": [
195 | {
196 | "internalType": "uint256",
197 | "name": "amountOut",
198 | "type": "uint256"
199 | }
200 | ],
201 | "stateMutability": "pure",
202 | "type": "function"
203 | },
204 | {
205 | "inputs": [
206 | {
207 | "internalType": "uint256",
208 | "name": "amountOut",
209 | "type": "uint256"
210 | },
211 | {
212 | "internalType": "address[]",
213 | "name": "path",
214 | "type": "address[]"
215 | }
216 | ],
217 | "name": "getAmountsIn",
218 | "outputs": [
219 | {
220 | "internalType": "uint256[]",
221 | "name": "amounts",
222 | "type": "uint256[]"
223 | }
224 | ],
225 | "stateMutability": "view",
226 | "type": "function"
227 | },
228 | {
229 | "inputs": [
230 | {
231 | "internalType": "uint256",
232 | "name": "amountIn",
233 | "type": "uint256"
234 | },
235 | {
236 | "internalType": "address[]",
237 | "name": "path",
238 | "type": "address[]"
239 | }
240 | ],
241 | "name": "getAmountsOut",
242 | "outputs": [
243 | {
244 | "internalType": "uint256[]",
245 | "name": "amounts",
246 | "type": "uint256[]"
247 | }
248 | ],
249 | "stateMutability": "view",
250 | "type": "function"
251 | },
252 | {
253 | "inputs": [
254 | {
255 | "internalType": "uint256",
256 | "name": "amountA",
257 | "type": "uint256"
258 | },
259 | {
260 | "internalType": "uint256",
261 | "name": "reserveA",
262 | "type": "uint256"
263 | },
264 | {
265 | "internalType": "uint256",
266 | "name": "reserveB",
267 | "type": "uint256"
268 | }
269 | ],
270 | "name": "quote",
271 | "outputs": [
272 | {
273 | "internalType": "uint256",
274 | "name": "amountB",
275 | "type": "uint256"
276 | }
277 | ],
278 | "stateMutability": "pure",
279 | "type": "function"
280 | },
281 | {
282 | "inputs": [
283 | {
284 | "internalType": "address",
285 | "name": "tokenA",
286 | "type": "address"
287 | },
288 | {
289 | "internalType": "address",
290 | "name": "tokenB",
291 | "type": "address"
292 | },
293 | {
294 | "internalType": "uint256",
295 | "name": "liquidity",
296 | "type": "uint256"
297 | },
298 | {
299 | "internalType": "uint256",
300 | "name": "amountAMin",
301 | "type": "uint256"
302 | },
303 | {
304 | "internalType": "uint256",
305 | "name": "amountBMin",
306 | "type": "uint256"
307 | },
308 | {
309 | "internalType": "address",
310 | "name": "to",
311 | "type": "address"
312 | },
313 | {
314 | "internalType": "uint256",
315 | "name": "deadline",
316 | "type": "uint256"
317 | }
318 | ],
319 | "name": "removeLiquidity",
320 | "outputs": [
321 | {
322 | "internalType": "uint256",
323 | "name": "amountA",
324 | "type": "uint256"
325 | },
326 | {
327 | "internalType": "uint256",
328 | "name": "amountB",
329 | "type": "uint256"
330 | }
331 | ],
332 | "stateMutability": "nonpayable",
333 | "type": "function"
334 | },
335 | {
336 | "inputs": [
337 | {
338 | "internalType": "address",
339 | "name": "token",
340 | "type": "address"
341 | },
342 | {
343 | "internalType": "uint256",
344 | "name": "liquidity",
345 | "type": "uint256"
346 | },
347 | {
348 | "internalType": "uint256",
349 | "name": "amountTokenMin",
350 | "type": "uint256"
351 | },
352 | {
353 | "internalType": "uint256",
354 | "name": "amountETHMin",
355 | "type": "uint256"
356 | },
357 | {
358 | "internalType": "address",
359 | "name": "to",
360 | "type": "address"
361 | },
362 | {
363 | "internalType": "uint256",
364 | "name": "deadline",
365 | "type": "uint256"
366 | }
367 | ],
368 | "name": "removeLiquidityETH",
369 | "outputs": [
370 | {
371 | "internalType": "uint256",
372 | "name": "amountToken",
373 | "type": "uint256"
374 | },
375 | {
376 | "internalType": "uint256",
377 | "name": "amountETH",
378 | "type": "uint256"
379 | }
380 | ],
381 | "stateMutability": "nonpayable",
382 | "type": "function"
383 | },
384 | {
385 | "inputs": [
386 | {
387 | "internalType": "address",
388 | "name": "token",
389 | "type": "address"
390 | },
391 | {
392 | "internalType": "uint256",
393 | "name": "liquidity",
394 | "type": "uint256"
395 | },
396 | {
397 | "internalType": "uint256",
398 | "name": "amountTokenMin",
399 | "type": "uint256"
400 | },
401 | {
402 | "internalType": "uint256",
403 | "name": "amountETHMin",
404 | "type": "uint256"
405 | },
406 | {
407 | "internalType": "address",
408 | "name": "to",
409 | "type": "address"
410 | },
411 | {
412 | "internalType": "uint256",
413 | "name": "deadline",
414 | "type": "uint256"
415 | },
416 | {
417 | "internalType": "bool",
418 | "name": "approveMax",
419 | "type": "bool"
420 | },
421 | {
422 | "internalType": "uint8",
423 | "name": "v",
424 | "type": "uint8"
425 | },
426 | {
427 | "internalType": "bytes32",
428 | "name": "r",
429 | "type": "bytes32"
430 | },
431 | {
432 | "internalType": "bytes32",
433 | "name": "s",
434 | "type": "bytes32"
435 | }
436 | ],
437 | "name": "removeLiquidityETHWithPermit",
438 | "outputs": [
439 | {
440 | "internalType": "uint256",
441 | "name": "amountToken",
442 | "type": "uint256"
443 | },
444 | {
445 | "internalType": "uint256",
446 | "name": "amountETH",
447 | "type": "uint256"
448 | }
449 | ],
450 | "stateMutability": "nonpayable",
451 | "type": "function"
452 | },
453 | {
454 | "inputs": [
455 | {
456 | "internalType": "address",
457 | "name": "tokenA",
458 | "type": "address"
459 | },
460 | {
461 | "internalType": "address",
462 | "name": "tokenB",
463 | "type": "address"
464 | },
465 | {
466 | "internalType": "uint256",
467 | "name": "liquidity",
468 | "type": "uint256"
469 | },
470 | {
471 | "internalType": "uint256",
472 | "name": "amountAMin",
473 | "type": "uint256"
474 | },
475 | {
476 | "internalType": "uint256",
477 | "name": "amountBMin",
478 | "type": "uint256"
479 | },
480 | {
481 | "internalType": "address",
482 | "name": "to",
483 | "type": "address"
484 | },
485 | {
486 | "internalType": "uint256",
487 | "name": "deadline",
488 | "type": "uint256"
489 | },
490 | {
491 | "internalType": "bool",
492 | "name": "approveMax",
493 | "type": "bool"
494 | },
495 | {
496 | "internalType": "uint8",
497 | "name": "v",
498 | "type": "uint8"
499 | },
500 | {
501 | "internalType": "bytes32",
502 | "name": "r",
503 | "type": "bytes32"
504 | },
505 | {
506 | "internalType": "bytes32",
507 | "name": "s",
508 | "type": "bytes32"
509 | }
510 | ],
511 | "name": "removeLiquidityWithPermit",
512 | "outputs": [
513 | {
514 | "internalType": "uint256",
515 | "name": "amountA",
516 | "type": "uint256"
517 | },
518 | {
519 | "internalType": "uint256",
520 | "name": "amountB",
521 | "type": "uint256"
522 | }
523 | ],
524 | "stateMutability": "nonpayable",
525 | "type": "function"
526 | },
527 | {
528 | "inputs": [
529 | {
530 | "internalType": "uint256",
531 | "name": "amountOut",
532 | "type": "uint256"
533 | },
534 | {
535 | "internalType": "address[]",
536 | "name": "path",
537 | "type": "address[]"
538 | },
539 | {
540 | "internalType": "address",
541 | "name": "to",
542 | "type": "address"
543 | },
544 | {
545 | "internalType": "uint256",
546 | "name": "deadline",
547 | "type": "uint256"
548 | }
549 | ],
550 | "name": "swapETHForExactTokens",
551 | "outputs": [
552 | {
553 | "internalType": "uint256[]",
554 | "name": "amounts",
555 | "type": "uint256[]"
556 | }
557 | ],
558 | "stateMutability": "payable",
559 | "type": "function"
560 | },
561 | {
562 | "inputs": [
563 | {
564 | "internalType": "uint256",
565 | "name": "amountOutMin",
566 | "type": "uint256"
567 | },
568 | {
569 | "internalType": "address[]",
570 | "name": "path",
571 | "type": "address[]"
572 | },
573 | {
574 | "internalType": "address",
575 | "name": "to",
576 | "type": "address"
577 | },
578 | {
579 | "internalType": "uint256",
580 | "name": "deadline",
581 | "type": "uint256"
582 | }
583 | ],
584 | "name": "swapExactETHForTokens",
585 | "outputs": [
586 | {
587 | "internalType": "uint256[]",
588 | "name": "amounts",
589 | "type": "uint256[]"
590 | }
591 | ],
592 | "stateMutability": "payable",
593 | "type": "function"
594 | },
595 | {
596 | "inputs": [
597 | {
598 | "internalType": "uint256",
599 | "name": "amountIn",
600 | "type": "uint256"
601 | },
602 | {
603 | "internalType": "uint256",
604 | "name": "amountOutMin",
605 | "type": "uint256"
606 | },
607 | {
608 | "internalType": "address[]",
609 | "name": "path",
610 | "type": "address[]"
611 | },
612 | {
613 | "internalType": "address",
614 | "name": "to",
615 | "type": "address"
616 | },
617 | {
618 | "internalType": "uint256",
619 | "name": "deadline",
620 | "type": "uint256"
621 | }
622 | ],
623 | "name": "swapExactTokensForETH",
624 | "outputs": [
625 | {
626 | "internalType": "uint256[]",
627 | "name": "amounts",
628 | "type": "uint256[]"
629 | }
630 | ],
631 | "stateMutability": "nonpayable",
632 | "type": "function"
633 | },
634 | {
635 | "inputs": [
636 | {
637 | "internalType": "uint256",
638 | "name": "amountIn",
639 | "type": "uint256"
640 | },
641 | {
642 | "internalType": "uint256",
643 | "name": "amountOutMin",
644 | "type": "uint256"
645 | },
646 | {
647 | "internalType": "address[]",
648 | "name": "path",
649 | "type": "address[]"
650 | },
651 | {
652 | "internalType": "address",
653 | "name": "to",
654 | "type": "address"
655 | },
656 | {
657 | "internalType": "uint256",
658 | "name": "deadline",
659 | "type": "uint256"
660 | }
661 | ],
662 | "name": "swapExactTokensForTokens",
663 | "outputs": [
664 | {
665 | "internalType": "uint256[]",
666 | "name": "amounts",
667 | "type": "uint256[]"
668 | }
669 | ],
670 | "stateMutability": "nonpayable",
671 | "type": "function"
672 | },
673 | {
674 | "inputs": [
675 | {
676 | "internalType": "uint256",
677 | "name": "amountOut",
678 | "type": "uint256"
679 | },
680 | {
681 | "internalType": "uint256",
682 | "name": "amountInMax",
683 | "type": "uint256"
684 | },
685 | {
686 | "internalType": "address[]",
687 | "name": "path",
688 | "type": "address[]"
689 | },
690 | {
691 | "internalType": "address",
692 | "name": "to",
693 | "type": "address"
694 | },
695 | {
696 | "internalType": "uint256",
697 | "name": "deadline",
698 | "type": "uint256"
699 | }
700 | ],
701 | "name": "swapTokensForExactETH",
702 | "outputs": [
703 | {
704 | "internalType": "uint256[]",
705 | "name": "amounts",
706 | "type": "uint256[]"
707 | }
708 | ],
709 | "stateMutability": "nonpayable",
710 | "type": "function"
711 | },
712 | {
713 | "inputs": [
714 | {
715 | "internalType": "uint256",
716 | "name": "amountOut",
717 | "type": "uint256"
718 | },
719 | {
720 | "internalType": "uint256",
721 | "name": "amountInMax",
722 | "type": "uint256"
723 | },
724 | {
725 | "internalType": "address[]",
726 | "name": "path",
727 | "type": "address[]"
728 | },
729 | {
730 | "internalType": "address",
731 | "name": "to",
732 | "type": "address"
733 | },
734 | {
735 | "internalType": "uint256",
736 | "name": "deadline",
737 | "type": "uint256"
738 | }
739 | ],
740 | "name": "swapTokensForExactTokens",
741 | "outputs": [
742 | {
743 | "internalType": "uint256[]",
744 | "name": "amounts",
745 | "type": "uint256[]"
746 | }
747 | ],
748 | "stateMutability": "nonpayable",
749 | "type": "function"
750 | }
751 | ]
752 |
--------------------------------------------------------------------------------