├── .gitignore
├── .sass-cache
├── c7cbbc39cd3a5dac9be2e4a5062de59e41cc6ff5
│ └── minima.scssc
└── db85969e9cbc40af68be6066a9b54d49788ef835
│ ├── _base.scssc
│ ├── _layout.scssc
│ └── _syntax-highlighting.scssc
├── Gemfile
├── Gemfile.lock
├── README.md
├── _config.yml
├── _includes
└── toc.html
├── _layouts
└── default.html
├── assets
└── css
│ └── style.css
├── chapters
├── asset.md
├── definitions.md
├── exchanges.md
├── factory.md
├── fund.md
├── governance.md
├── melon_engine.md
├── prices.md
├── registry.md
└── version.md
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | /public
2 | /node_modules
3 | /dist/docs/
4 | /_site
5 | .sass-cache
6 |
7 | .now
--------------------------------------------------------------------------------
/.sass-cache/c7cbbc39cd3a5dac9be2e4a5062de59e41cc6ff5/minima.scssc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/melonproject-archive/documentation/9f32909fd950c904300228df23bb440c2df4dbab/.sass-cache/c7cbbc39cd3a5dac9be2e4a5062de59e41cc6ff5/minima.scssc
--------------------------------------------------------------------------------
/.sass-cache/db85969e9cbc40af68be6066a9b54d49788ef835/_base.scssc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/melonproject-archive/documentation/9f32909fd950c904300228df23bb440c2df4dbab/.sass-cache/db85969e9cbc40af68be6066a9b54d49788ef835/_base.scssc
--------------------------------------------------------------------------------
/.sass-cache/db85969e9cbc40af68be6066a9b54d49788ef835/_layout.scssc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/melonproject-archive/documentation/9f32909fd950c904300228df23bb440c2df4dbab/.sass-cache/db85969e9cbc40af68be6066a9b54d49788ef835/_layout.scssc
--------------------------------------------------------------------------------
/.sass-cache/db85969e9cbc40af68be6066a9b54d49788ef835/_syntax-highlighting.scssc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/melonproject-archive/documentation/9f32909fd950c904300228df23bb440c2df4dbab/.sass-cache/db85969e9cbc40af68be6066a9b54d49788ef835/_syntax-highlighting.scssc
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 | gem 'github-pages', group: :jekyll_plugins
3 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | activesupport (6.0.3.1)
5 | concurrent-ruby (~> 1.0, >= 1.0.2)
6 | i18n (>= 0.7, < 2)
7 | minitest (~> 5.1)
8 | tzinfo (~> 1.1)
9 | zeitwerk (~> 2.2, >= 2.2.2)
10 | addressable (2.7.0)
11 | public_suffix (>= 2.0.2, < 5.0)
12 | coffee-script (2.4.1)
13 | coffee-script-source
14 | execjs
15 | coffee-script-source (1.11.1)
16 | colorator (1.1.0)
17 | commonmarker (0.17.13)
18 | ruby-enum (~> 0.5)
19 | concurrent-ruby (1.1.6)
20 | dnsruby (1.61.3)
21 | addressable (~> 2.5)
22 | em-websocket (0.5.1)
23 | eventmachine (>= 0.12.9)
24 | http_parser.rb (~> 0.6.0)
25 | ethon (0.12.0)
26 | ffi (>= 1.3.0)
27 | eventmachine (1.2.7)
28 | execjs (2.7.0)
29 | faraday (1.0.1)
30 | multipart-post (>= 1.2, < 3)
31 | ffi (1.12.2)
32 | forwardable-extended (2.6.0)
33 | gemoji (3.0.1)
34 | github-pages (204)
35 | github-pages-health-check (= 1.16.1)
36 | jekyll (= 3.8.5)
37 | jekyll-avatar (= 0.7.0)
38 | jekyll-coffeescript (= 1.1.1)
39 | jekyll-commonmark-ghpages (= 0.1.6)
40 | jekyll-default-layout (= 0.1.4)
41 | jekyll-feed (= 0.13.0)
42 | jekyll-gist (= 1.5.0)
43 | jekyll-github-metadata (= 2.13.0)
44 | jekyll-mentions (= 1.5.1)
45 | jekyll-optional-front-matter (= 0.3.2)
46 | jekyll-paginate (= 1.1.0)
47 | jekyll-readme-index (= 0.3.0)
48 | jekyll-redirect-from (= 0.15.0)
49 | jekyll-relative-links (= 0.6.1)
50 | jekyll-remote-theme (= 0.4.1)
51 | jekyll-sass-converter (= 1.5.2)
52 | jekyll-seo-tag (= 2.6.1)
53 | jekyll-sitemap (= 1.4.0)
54 | jekyll-swiss (= 1.0.0)
55 | jekyll-theme-architect (= 0.1.1)
56 | jekyll-theme-cayman (= 0.1.1)
57 | jekyll-theme-dinky (= 0.1.1)
58 | jekyll-theme-hacker (= 0.1.1)
59 | jekyll-theme-leap-day (= 0.1.1)
60 | jekyll-theme-merlot (= 0.1.1)
61 | jekyll-theme-midnight (= 0.1.1)
62 | jekyll-theme-minimal (= 0.1.1)
63 | jekyll-theme-modernist (= 0.1.1)
64 | jekyll-theme-primer (= 0.5.4)
65 | jekyll-theme-slate (= 0.1.1)
66 | jekyll-theme-tactile (= 0.1.1)
67 | jekyll-theme-time-machine (= 0.1.1)
68 | jekyll-titles-from-headings (= 0.5.3)
69 | jemoji (= 0.11.1)
70 | kramdown (= 1.17.0)
71 | liquid (= 4.0.3)
72 | mercenary (~> 0.3)
73 | minima (= 2.5.1)
74 | nokogiri (>= 1.10.4, < 2.0)
75 | rouge (= 3.13.0)
76 | terminal-table (~> 1.4)
77 | github-pages-health-check (1.16.1)
78 | addressable (~> 2.3)
79 | dnsruby (~> 1.60)
80 | octokit (~> 4.0)
81 | public_suffix (~> 3.0)
82 | typhoeus (~> 1.3)
83 | html-pipeline (2.12.3)
84 | activesupport (>= 2)
85 | nokogiri (>= 1.4)
86 | http_parser.rb (0.6.0)
87 | i18n (0.9.5)
88 | concurrent-ruby (~> 1.0)
89 | jekyll (3.8.5)
90 | addressable (~> 2.4)
91 | colorator (~> 1.0)
92 | em-websocket (~> 0.5)
93 | i18n (~> 0.7)
94 | jekyll-sass-converter (~> 1.0)
95 | jekyll-watch (~> 2.0)
96 | kramdown (~> 1.14)
97 | liquid (~> 4.0)
98 | mercenary (~> 0.3.3)
99 | pathutil (~> 0.9)
100 | rouge (>= 1.7, < 4)
101 | safe_yaml (~> 1.0)
102 | jekyll-avatar (0.7.0)
103 | jekyll (>= 3.0, < 5.0)
104 | jekyll-coffeescript (1.1.1)
105 | coffee-script (~> 2.2)
106 | coffee-script-source (~> 1.11.1)
107 | jekyll-commonmark (1.3.1)
108 | commonmarker (~> 0.14)
109 | jekyll (>= 3.7, < 5.0)
110 | jekyll-commonmark-ghpages (0.1.6)
111 | commonmarker (~> 0.17.6)
112 | jekyll-commonmark (~> 1.2)
113 | rouge (>= 2.0, < 4.0)
114 | jekyll-default-layout (0.1.4)
115 | jekyll (~> 3.0)
116 | jekyll-feed (0.13.0)
117 | jekyll (>= 3.7, < 5.0)
118 | jekyll-gist (1.5.0)
119 | octokit (~> 4.2)
120 | jekyll-github-metadata (2.13.0)
121 | jekyll (>= 3.4, < 5.0)
122 | octokit (~> 4.0, != 4.4.0)
123 | jekyll-mentions (1.5.1)
124 | html-pipeline (~> 2.3)
125 | jekyll (>= 3.7, < 5.0)
126 | jekyll-optional-front-matter (0.3.2)
127 | jekyll (>= 3.0, < 5.0)
128 | jekyll-paginate (1.1.0)
129 | jekyll-readme-index (0.3.0)
130 | jekyll (>= 3.0, < 5.0)
131 | jekyll-redirect-from (0.15.0)
132 | jekyll (>= 3.3, < 5.0)
133 | jekyll-relative-links (0.6.1)
134 | jekyll (>= 3.3, < 5.0)
135 | jekyll-remote-theme (0.4.1)
136 | addressable (~> 2.0)
137 | jekyll (>= 3.5, < 5.0)
138 | rubyzip (>= 1.3.0)
139 | jekyll-sass-converter (1.5.2)
140 | sass (~> 3.4)
141 | jekyll-seo-tag (2.6.1)
142 | jekyll (>= 3.3, < 5.0)
143 | jekyll-sitemap (1.4.0)
144 | jekyll (>= 3.7, < 5.0)
145 | jekyll-swiss (1.0.0)
146 | jekyll-theme-architect (0.1.1)
147 | jekyll (~> 3.5)
148 | jekyll-seo-tag (~> 2.0)
149 | jekyll-theme-cayman (0.1.1)
150 | jekyll (~> 3.5)
151 | jekyll-seo-tag (~> 2.0)
152 | jekyll-theme-dinky (0.1.1)
153 | jekyll (~> 3.5)
154 | jekyll-seo-tag (~> 2.0)
155 | jekyll-theme-hacker (0.1.1)
156 | jekyll (~> 3.5)
157 | jekyll-seo-tag (~> 2.0)
158 | jekyll-theme-leap-day (0.1.1)
159 | jekyll (~> 3.5)
160 | jekyll-seo-tag (~> 2.0)
161 | jekyll-theme-merlot (0.1.1)
162 | jekyll (~> 3.5)
163 | jekyll-seo-tag (~> 2.0)
164 | jekyll-theme-midnight (0.1.1)
165 | jekyll (~> 3.5)
166 | jekyll-seo-tag (~> 2.0)
167 | jekyll-theme-minimal (0.1.1)
168 | jekyll (~> 3.5)
169 | jekyll-seo-tag (~> 2.0)
170 | jekyll-theme-modernist (0.1.1)
171 | jekyll (~> 3.5)
172 | jekyll-seo-tag (~> 2.0)
173 | jekyll-theme-primer (0.5.4)
174 | jekyll (> 3.5, < 5.0)
175 | jekyll-github-metadata (~> 2.9)
176 | jekyll-seo-tag (~> 2.0)
177 | jekyll-theme-slate (0.1.1)
178 | jekyll (~> 3.5)
179 | jekyll-seo-tag (~> 2.0)
180 | jekyll-theme-tactile (0.1.1)
181 | jekyll (~> 3.5)
182 | jekyll-seo-tag (~> 2.0)
183 | jekyll-theme-time-machine (0.1.1)
184 | jekyll (~> 3.5)
185 | jekyll-seo-tag (~> 2.0)
186 | jekyll-titles-from-headings (0.5.3)
187 | jekyll (>= 3.3, < 5.0)
188 | jekyll-watch (2.2.1)
189 | listen (~> 3.0)
190 | jemoji (0.11.1)
191 | gemoji (~> 3.0)
192 | html-pipeline (~> 2.2)
193 | jekyll (>= 3.0, < 5.0)
194 | kramdown (1.17.0)
195 | liquid (4.0.3)
196 | listen (3.2.1)
197 | rb-fsevent (~> 0.10, >= 0.10.3)
198 | rb-inotify (~> 0.9, >= 0.9.10)
199 | mercenary (0.3.6)
200 | mini_portile2 (2.4.0)
201 | minima (2.5.1)
202 | jekyll (>= 3.5, < 5.0)
203 | jekyll-feed (~> 0.9)
204 | jekyll-seo-tag (~> 2.1)
205 | minitest (5.14.1)
206 | multipart-post (2.1.1)
207 | nokogiri (1.10.9)
208 | mini_portile2 (~> 2.4.0)
209 | octokit (4.18.0)
210 | faraday (>= 0.9)
211 | sawyer (~> 0.8.0, >= 0.5.3)
212 | pathutil (0.16.2)
213 | forwardable-extended (~> 2.6)
214 | public_suffix (3.1.1)
215 | rb-fsevent (0.10.4)
216 | rb-inotify (0.10.1)
217 | ffi (~> 1.0)
218 | rouge (3.13.0)
219 | ruby-enum (0.8.0)
220 | i18n
221 | rubyzip (2.3.0)
222 | safe_yaml (1.0.5)
223 | sass (3.7.4)
224 | sass-listen (~> 4.0.0)
225 | sass-listen (4.0.0)
226 | rb-fsevent (~> 0.9, >= 0.9.4)
227 | rb-inotify (~> 0.9, >= 0.9.7)
228 | sawyer (0.8.2)
229 | addressable (>= 2.3.5)
230 | faraday (> 0.8, < 2.0)
231 | terminal-table (1.8.0)
232 | unicode-display_width (~> 1.1, >= 1.1.1)
233 | thread_safe (0.3.6)
234 | typhoeus (1.3.1)
235 | ethon (>= 0.9.0)
236 | tzinfo (1.2.7)
237 | thread_safe (~> 0.1)
238 | unicode-display_width (1.7.0)
239 | zeitwerk (2.3.0)
240 |
241 | PLATFORMS
242 | ruby
243 |
244 | DEPENDENCIES
245 | github-pages
246 |
247 | BUNDLED WITH
248 | 2.1.2
249 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Melon Protocol Reference
2 |
3 | The Melon Protocol intends to present a decentralized, public, permissionless, robust infrastructure for the secure management of crypographic token assets on the Ethereum blockchain. It aims to be a viable, low-cost alternative to the current fund management ecosystem, which has evolved similarly across most legal jurisdictions.
4 |
5 | This Melon Protocol is a collection of smart contracts written in the Solidity programming language and deployed to the Ethereum blockchain. Supporting functionality allowing web browsers to freely interact with the protocol is provided by the javascript library, Melon.js.
6 |
7 | ## Motivation
8 | Today, starting and running an investment fund is an arduous and capital intensive endeavor. To a large degree, the applicable laws and requirements - formidable hurdles that have evolved over time - have originated in the singular ideal: to protect investor capital.
9 |
10 | The dizzying array of laws, regulations and requirements present obstacles to the practice of investment management. An individual or organization wishing to engage in investment management activities must be able to bear the costs to achieve compliance with their governing authorities. Initially, there are direct costs, such as legal and regulatory fees, set-up costs and service provider costs. Operating a fund incurs other indirect costs, such as maintaining regulatory reporting with back-office support staff, IT systems and integrations intended to satisfy requirements. The implication is that managing a fund is financially viable only after a certain scale of Assets Under Management. This scale is, in practice, quite significant. This necessarily reduces the number of managers by creating barriers to entry, resulting in an exclusive set of established players already operating at scale.
11 |
12 | We believe that choice is good and that investment management talent has no compelling reason to be subject to hurdles when certain trust-, legal- and regulatory touchpoints are provably and reliably provided by the Melon Protocol.
13 |
14 | Ultimately, the cost of what was initially intended as investor protection, is indeed borne by the investor, in that a portion of investment performance is consumed by these costs. We believe the Melon Protocol can achieve something the legacy investment management industry simply cannot: increasing investor protection, dramatically reducing the costs of fund operations, leveling the playing field for new and innovative managers, and making fund investment viable at any scale.
15 |
16 | ## Overview
17 |
18 | The Melon protocol can be seen as having two layers.
19 | One is of all the funds in existence, controlled by their respective managers, and participated in by investors.
20 | The second is of infrastructure-level contracts, managed by our governance system, and critical to maintaining a healthy ecosystem for funds.
21 |
22 | Each of the subsystems mentioned below are discussed in great detail elsewhere in the documentation.
23 | This article is meant to provide a high-level view of how the components are arranged, and a brief description of what each one does.
24 |
25 |
26 | ### The fund
27 |
28 | Each fund is a small constellation of smart contracts, each customized with parameters that the manager desires at creation time.
29 |
30 | At the core of the fund is a contract called the Hub.
31 | This contract tracks the rest of the components, which can be thought of as Spokes.
32 | The Hub also provides the methods necessary for setup of the fund, and maintains an access control list of which components can call which methods.
33 |
34 | The Vault component functions to simply store tokens on behalf of the fund, and segregate them from the rest of the components as a way to reduce surface area.
35 |
36 | One of these other components is the Shares component, which provides a unit of account for ownership in a fund.
37 | Shares are not tradeable, but are created and destroyed as the fund is entered and exited by investors.
38 |
39 | This entrypoint is provided by the Participation component.
40 | The functions on that contract allow investors to buy shares with one of some set of allowed assets, or to redeem them for a proportional "slice" of the fund's underlying assets.
41 | Share price determines the amount of shares created for a new investor, and the quantities of underlying assets given at redemption.
42 |
43 | The Accounting component provides this overall share price for the fund.
44 | It also tracks amounts of assets owned by the fund, and computes other metrics related to the share price (e.g. gross asset value).
45 | Furtermore, the Accounting component provides a method to trigger fee payment on the fund.
46 |
47 | Fees are rewarded to the manager at certain points during the lifetime of a fund, such as on redemption of shares, and at the end fo a designated reward period.
48 | There are currently two types of fees: management and performance fees, and they are tracked by the FeeManager component.
49 | Management fees are calculated based on time only, while the amount of performance fees given is determined by share price evolution.
50 |
51 | A manager tries to maximize their fund's performance by making favourable trades, using methods on the Trading component.
52 | This contract provides a transparent way to interact with multiple exchange types, through its use of exchange adapters.
53 |
54 | Managers are restricted from making bad trades beyond a certain threshold however, through rules implemented as part of the fund's risk management subsystem.
55 | These rules are also use to mitigate other malicious or negligent behaviour on behalf of the manager.
56 | The risk management rules are tracked in the Policy Manager component.
57 | Incidentally, investment in the fund via the Participation contract is also parameterized by rules called Compliance policies, which are also tracked by the Policy Manager.
58 |
59 | While a fund's behaviour is defined in its component contracts, much of its functionality is dependent on having working infrastructure surrounding it.
60 |
61 | ### Infrastructure contracts
62 |
63 | These contracts are deployed for the benefit of the entire network.
64 | They function to keep the entire system running, but are not controlled by individual fund managers or investors.
65 | Instead, they are managed by the governance system, or some component thereof.
66 |
67 | The fund factory is deployed for managers to create their funds on a particular protocol version.
68 | Factories for each of the types of fund component are also deployed independently, and are leveraged by the fund factory when producing new funds.
69 |
70 | Each exchange type also has a corresponding infrastructure *adapter* contract, which is shared by all funds.
71 | The adapter simply converts "generic" exchange methods on a fund's Trading component to methods that particular exchanges expect.
72 |
73 | The Registry contract provides a high-level interface for what other infrastructure contracts know about.
74 |
75 | One of the addresses tracked is that of the Engine contract.
76 | The Engine uses a buy-and-burn model discussed elsewhere in the documentation, taking MLN out of circulation by buying it for ETH.
77 | The ETH used is accumulated by the Engine as funds pay for and perform certain actions.
78 |
79 | Another contract which is tracked by the Registry is the Price Source for the entire system.
80 | The Price Source is critical to the proper operation of funds, since it yields information used in many of a fund's actions, such as investment, redemption and fee payment.
81 |
82 | As mentioned above, the infrastructure layer is managed by Governance.
83 | More information on how governance is structured and operated is described in the Governance documentation.
84 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 |
2 | title: "Melon"
3 | description: "Documentation Reference"
4 | submodule_section: "Submodules"
5 | submodules: "brief"
6 | repository: melonproject/documentation
7 |
--------------------------------------------------------------------------------
/_includes/toc.html:
--------------------------------------------------------------------------------
1 | {% capture tocWorkspace %}
2 | {% comment %}
3 | Using Allejo's Jekyll TOC version 1.0.4
4 | https://github.com/allejo/jekyll-toc
5 | {% endcomment %}
6 |
7 | {% capture my_toc %}{% endcapture %}
8 | {% assign orderedList = include.ordered | default: false %}
9 | {% assign minHeader = include.h_min | default: 1 %}
10 | {% assign maxHeader = include.h_max | default: 6 %}
11 | {% assign nodes = include.html | markdownify | split: ' maxHeader %}
21 | {% continue %}
22 | {% endif %}
23 | {% comment %}
24 | This block assumes the first heading in an md file is the highest level one
25 | {% endcomment %}
26 | {% if firstHeader %}
27 | {% assign minHeader = headerLevel %}
28 | {% endif %}
29 | {% if fixed_header %}
30 | {% increment headerLevel %}
31 | {% endif %}
32 | {% assign indentAmount = headerLevel | minus: minHeader | add: 1 %}
33 | {% assign _workspace = node | split: '' | first }}>{% endcapture %}
38 | {% assign header = _workspace[0] | replace: _hAttrToStrip, '' %}
39 | {% assign space = '' %}
40 | {% for i in (1..indentAmount) %}
41 | {% assign space = space | prepend: ' ' %}
42 | {% endfor %}
43 | {% assign spaceNext = space | prepend: ' ' %}
44 | {% unless include.item_class == blank %}
45 | {% capture listItemClass %}{:.{{ include.item_class | replace: '%level%', headerLevel }}}{% endcapture %}
46 | {% endunless %}
47 | {% capture url %}{{ site.baseurl }}{{ include.url }}#{{ html_id }}{% endcapture %}
48 | {% capture label %}{% if include.sanitize %}{{ header | strip_html }}{% else %}{{ header }}{% endif %}{% endcapture %}
49 | {% assign id = url | replace:'/','_'| replace:'#','_' %}
50 | {% if firstHeader %}
51 | {% capture my_toc %}{{ my_toc }}
52 | {{ space }}{{ listModifier }} {{ listItemClass }}
53 | {% else %}>{% endif %}{% endcapture %}
54 | {% capture my_toc %}{{ my_toc }}
55 | {{ spaceNext }}{{ listModifier }} {{ listItemClass }} [Introduction]({{ url }}){% endcapture %}
56 | {% else %}
57 | {% capture my_toc %}{{ my_toc }}
58 | {{ space }}{{ listModifier }} {{ listItemClass }} [{{ label }}]({%if firstHeader %}#{% else %}{{ url }}{% endif %}){% endcapture %}
59 | {% endif %}
60 | {% assign firstHeader = false %}
61 | {% endfor %}
62 | {% if include.class %}
63 | {% capture my_toc %}{:.{{ include.class }}}
64 | {{ my_toc | lstrip }}{% endcapture %}
65 | {% endif %}
66 | {% if include.id %}
67 | {% capture my_toc %}{: /#{{ include.id }}}
68 | {{ my_toc | lstrip }}{% endcapture %}
69 | {% endif %}
70 | {% endcapture %}{% assign tocWorkspace = '' %}{{ my_toc | markdownify | strip }}
--------------------------------------------------------------------------------
/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | {{ content }}
15 |
16 |
17 |
101 |
102 |
103 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/assets/css/style.css:
--------------------------------------------------------------------------------
1 | /* Layout */
2 |
3 | * {
4 | box-sizing: border-box;
5 | }
6 |
7 | body {
8 | display: flex;
9 | flex-direction: column;
10 | margin: 0;
11 | }
12 |
13 | main {
14 | display: flex;
15 | justify-content: center;
16 | position: relative;
17 | padding-bottom: 64px;
18 | margin-left: 320px;
19 | min-height: 100vh;
20 | }
21 |
22 | main img {
23 | max-width: 100%;
24 | }
25 |
26 | section {
27 | width: 720px;
28 | max-width: 100%;
29 | padding: 16px 0 16px 48px;
30 | }
31 |
32 | footer {
33 | width: 100%;
34 | padding: 32px 24px;
35 | margin-top: 80px;
36 | }
37 |
38 | /* Typography */
39 |
40 | body {
41 | font-family: SourceSerifPro;
42 | -webkit-font-smoothing: antialiased;
43 | -moz-osx-font-smoothing: grayscale;
44 | text-rendering: optimizeLegibility;
45 | font-size: 14px;
46 | }
47 |
48 |
49 | h1,
50 | h2,
51 | h3,
52 | h4,
53 | h5 {
54 | font-weight: 300;
55 | margin-bottom: 8px;
56 | }
57 |
58 | h1 {
59 | font-size: 30px;
60 | margin-top: 0px;
61 | padding-top: 64px;
62 | }
63 |
64 | h2 {
65 | font-size: 24px;
66 | margin-top: 0px;
67 | padding-top: 72px;
68 | }
69 |
70 | h3 {
71 | font-size: 20px;
72 | margin-top: 0px;
73 | padding-top: 24px;
74 | }
75 |
76 | h4 {
77 | font-size: 16px;
78 | margin-top: 0px;
79 | padding-top: 24px;
80 | font-weight: 500;
81 | }
82 |
83 | h2+p,
84 | h3+p {
85 | padding-top: 0;
86 | }
87 |
88 | h1+h2 {
89 | padding-top: 40px;
90 | }
91 |
92 | h2+h3 {
93 | padding-top: 16px;
94 | }
95 |
96 | h2:before{
97 | content: '';
98 | margin-top: 80px;
99 | /* display: block; */
100 | position: relative;
101 | }
102 |
103 | p,
104 | ul,
105 | ol,
106 | table,
107 | pre,
108 | dl {
109 | margin-bottom: 24px;
110 | line-height: 24px;
111 | }
112 |
113 | strong {
114 | font-weight: 700;
115 | }
116 |
117 | /* Colors */
118 |
119 | body {
120 | color: #333;
121 | background-color: white;
122 | position: relative;
123 | }
124 |
125 | footer {
126 | background-color: #333;
127 | color: white;
128 | }
129 |
130 | footer a {
131 | color: white;
132 | }
133 |
134 | /* Lists */
135 |
136 | ul,
137 | ol {
138 | padding-left: 24px;
139 | }
140 |
141 | ul>li,
142 | ol>li {
143 | padding-bottom: 8px;
144 | }
145 |
146 | li>ul {
147 | padding-top: 8px;
148 | }
149 |
150 |
151 |
152 |
153 |
154 | /* Tables */
155 |
156 | table {
157 | border-collapse: collapse;
158 | }
159 |
160 | th {
161 | white-space: nowrap;
162 | text-align: left;
163 | }
164 |
165 | th,
166 | td {
167 | padding: 8px;
168 | }
169 |
170 | th {
171 | border-bottom: 1px solid rgba(0, 0, 0, 0.5);
172 | }
173 |
174 | td {
175 | border-bottom: 1px solid rgba(0, 0, 0, 0.1);
176 | min-width: 96px;
177 | }
178 |
179 | td:first-child {
180 | width: 120px;
181 | }
182 |
183 | th:first-child,
184 | td:first-child {
185 | padding-left: 0;
186 | }
187 |
188 | th:first-child {
189 | width: 272px;
190 | }
191 |
192 | th:nth-child(2),
193 | td:nth-child(2) {
194 | width: 104px;
195 | text-align: center;
196 | }
197 |
198 | td:nth-child(3):not(:last-child),
199 | th:nth-child(3):not(:last-child) {
200 | min-width: 112px;
201 | text-align: center;
202 | }
203 |
204 |
205 |
206 | /* four items */
207 |
208 | th:first-child:nth-last-child(4) {
209 | width: 172px;
210 | }
211 |
212 |
213 |
214 |
215 | /* Links */
216 |
217 | a {
218 | text-decoration: none;
219 | border-bottom: 1px solid transparent;
220 | color: var(--cta-color);
221 | }
222 |
223 | a:hover {
224 | border-bottom: 1px solid var(--cta-color);
225 | font-weight: 400;
226 | color: var(--cta-color);
227 | }
228 |
229 | h1:hover a,
230 | h2:hover a,
231 | h3:hover a,
232 | h4:hover a,
233 | h5:hover a {
234 | border-bottom: none;
235 | }
236 |
237 | h1:hover a:after,
238 | h2:hover a:after,
239 | h3:hover a:after,
240 | h4:hover a:after,
241 | h5:hover a:after {
242 | content: "";
243 | background: url('data:image/svg+xml;utf8,') no-repeat;
244 | display: inline-block;
245 | width: 16px;
246 | height: 18px;
247 | margin-left: 0.4em;
248 | }
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 | /* Code */
257 |
258 | code {
259 | font-size: 13px;
260 | background: #efefef;
261 | padding: 2px 4px;
262 | border-radius: 2px;
263 | margin-right: 2px;
264 | color: #222;
265 | }
266 |
267 |
268 | /* Table of Contents */
269 |
270 |
271 | aside {
272 | position: fixed;
273 | top: 0;
274 | left: 0;
275 | bottom: 0;
276 | width: 320px;
277 | max-width: 100%;
278 | padding: 16px 0px 16px 16px;
279 | display: flex;
280 | flex-direction: column;
281 | align-items: stretch;
282 | transition: transform 300ms;
283 |
284 | background-color: #f8f8f8;
285 | border: solid 1px #e0e0e0;
286 | }
287 |
288 | nav {
289 | margin-top: 24px;
290 | margin-bottom: 24px;
291 | padding-left: 0;
292 | flex-grow: 1;
293 | overflow-x: hidden;
294 | overflow-y: auto;
295 | position: relative;
296 | left: -8px;
297 | }
298 |
299 | nav li {
300 | list-style: none;
301 | }
302 |
303 | nav ul {
304 | margin-bottom: 0;
305 | }
306 |
307 | nav>ul {
308 | padding-left: 0;
309 | margin-top: 8px;
310 | }
311 |
312 | li>ul>li:last-child {
313 | padding-bottom: 0;
314 | }
315 |
316 | nav li {
317 | position: relative;
318 | line-height: 24px;
319 | padding-left: 8px;
320 | }
321 |
322 | nav li a {
323 | color: black;
324 | opacity: 0.6;
325 | transition: opacity 300ms;
326 | will-change: opacity;
327 | }
328 |
329 | nav li a:hover {
330 | border-bottom: none;
331 | color: black;
332 | opacity: 1;
333 | display: inline;
334 | }
335 |
336 | nav li > label + input {
337 | display: none;
338 | }
339 |
340 | nav li > label + input {
341 | display: none;
342 | }
343 |
344 | nav li > a::before,
345 | nav li > label::before {
346 | content: '';
347 | position: absolute;
348 | left: -8px;
349 | right: 0;
350 | height: 32px;
351 | margin-top: -4px;
352 | background-color: rgba(0, 0, 0, 0.05);
353 | opacity: 0;
354 | }
355 |
356 | nav li > a:hover::before,
357 | nav li > label:hover::before {
358 | opacity: 1;
359 | }
360 |
361 | nav ul.active-toc > li > a{
362 | font-weight: 700;
363 | }
364 |
365 | nav ul.active-toc > li > a:before{
366 | content: '>';
367 | position: absolute;
368 | margin-left: -24px;
369 | margin-top: -1px;
370 | }
371 |
372 | nav > ul > li > ul > li, nav > ul > li > ul {
373 | max-height: 6rem;
374 | opacity: 1;
375 | will-change: opacity;
376 | overflow: hidden;
377 | transition: max-height 300ms, opacity 200ms, margin-top 300ms;
378 | }
379 |
380 | nav > ul > li > ul {
381 | max-height: 100rem;
382 | }
383 |
384 | nav > ul > li > :checked ~ ul > li, nav > ul > li > :checked ~ ul {
385 | opacity: 0;
386 | max-height: 0;
387 | padding-top: 0;
388 | }
389 |
390 | nav > ul > li > :checked ~ ul > li > a:before {
391 | display: none;
392 | }
393 |
394 |
395 |
396 |
397 | /* Logo */
398 |
399 | a.logo {
400 | display: block;
401 | border-bottom: none;
402 | margin-left: 0;
403 | }
404 |
405 | .logo h1 {
406 | text-transform: uppercase;
407 | letter-spacing: 0.14em;
408 | font-weight: 800;
409 | color: rgb(90, 90, 90);
410 | white-space: nowrap;
411 | }
412 |
413 | .logo h1+p {
414 | font-weight: 700;
415 | text-transform: uppercase;
416 | letter-spacing: 0.12em;
417 | font-size: 15px;
418 | color: rgba(0, 0, 0, 0.7);
419 | margin-top: 0px;
420 | margin-bottom: 0;
421 | }
422 |
423 | /* Code */
424 |
425 | pre code{
426 | display: block;
427 | padding: 16px;
428 | user-select: all;
429 | border-radius: 4px;
430 | }
431 |
432 | /* Responsiveness */
433 |
434 | /* all touch devices */
435 | @media (max-width: 1040px) {
436 | table {
437 | overflow: auto;
438 | width: 100%;
439 | display: block;
440 | box-shadow: inset -5px 0px 7px #fefefe;
441 | }
442 |
443 | section {
444 | width: 100%;
445 | }
446 |
447 | main {
448 | margin-left: 0;
449 | overflow-x: scroll;
450 | justify-content: flex-start;
451 | }
452 |
453 | section {
454 | width: auto;
455 | padding: 24px;
456 | }
457 |
458 | aside {
459 | transform: translate(-100%);
460 | box-shadow: var(--box-shadow);
461 | width: 312px;
462 | z-index: 1;
463 | padding: 16px 24px 16px 56px;
464 | }
465 |
466 | aside:target {
467 | transform: translate(0);
468 | }
469 |
470 | #search-container:not(.nothing-found) nav {
471 | left: -16px;
472 | }
473 |
474 | a#nav-button{
475 | position: fixed;
476 | top: 0;
477 | left: 0;
478 | right: 0;
479 | padding: 24px 24px;
480 | border-bottom: none;
481 | display: flex;
482 | align-items: center;
483 | color: #555;
484 | background-color: white;
485 | }
486 |
487 | #nav-backdrop{
488 | position: fixed;
489 | top: 0;
490 | left: 0;
491 | bottom: 0;
492 | right: 0;
493 | background-color: rgba(0, 0, 0, 0.5);
494 | opacity: 0;
495 | transition: opacity 300ms;
496 | pointer-events: none;
497 | }
498 |
499 | aside:target + #nav-backdrop {
500 | pointer-events: all;
501 | opacity: 1;
502 | }
503 |
504 | .improve-me {
505 | bottom: 16px;
506 | right: 16px;
507 | }
508 |
509 | .logo h1{
510 | font-size: 24px;
511 | margin-bottom: 2px;
512 | }
513 |
514 | .logo h1+p{
515 | font-size: 13px;
516 | }
517 |
518 | nav ul.active-toc > li > a:before{
519 | margin-left: -20px;
520 | }
521 | }
522 |
523 |
524 |
525 | /* all click devices */
526 | @media (min-width: 1041px) {
527 | main {
528 | margin-left: 400px;
529 | }
530 |
531 | aside {
532 | width: 400px;
533 | padding: 10px 8px 16px 65px;
534 | }
535 | }
536 |
537 | /* desktop-xlarge */
538 | @media (min-width: 1601px){
539 | main {
540 | margin-left: 0;
541 | }
542 | }
543 |
--------------------------------------------------------------------------------
/chapters/asset.md:
--------------------------------------------------------------------------------
1 | # Assets
2 |
3 | Token assets are the underlying constituent members of a Melon Fund. These token assets are exclusively Ethereum blockchain tokens implementing the ERC20 standard token interface.
4 |
5 | ## Asset Eligibility
6 |
7 | In its governance capacity, the Technical Council determines the Melon Fund asset universe, in that it periodically analyzes the broader Ethereum token universe, seeking eligible tokens given their exchange membership, liquidity and underlying use in the context of asset management.
8 |
9 | Technically, a Melon Fund can hold any ERC20 compliant token. However, not all ERC20 compliant tokens are appropriate for Melon Funds to hold due to lack of a market, current pricing, exchange listing, liquidity, etc.
10 |
11 | ## ETH is not ERC20
12 |
13 | It should be noted the the Ethereum native asset, ETH, does _not_ comply with the ERC20 token standard. For this reason, market observers may occasionally see "Wrapped ETH" or "WETH", where ETH is itself held in an ERC20 compliant wrapper contract, so as to have the same behavior when participating in smart contract infrastructure that expects the ERC20 interface. As such, the Melon Fund cannot hold native ETH, but can only hold WETH. This has no impact on the valuation of ETH and will function and be valued like-for-like in the Melon Fund.
14 |
15 | ## Note on Gas
16 |
17 | It should be understood that non-view function interaction with an Ethereum smart contract requires the payment of gas for processing capacity. Gas is priced (dynamically according to network load and capacity) in ETH, so some amount of ETH in a calling address is required. Depending on the complexity and computational intensity of a smart contract, it is possible that non-trivial amounts of ETH may be required.
18 |
19 | Please refer to the Asset Registrar for more details.
20 |
--------------------------------------------------------------------------------
/chapters/definitions.md:
--------------------------------------------------------------------------------
1 | # Definitions
2 |
3 | ## Melon Fund
4 | A Melon Fund is an Ethereum smart contract deployed to the Ethereum blockchain. It is the core smart contract of the Melon Protocol. The Melon Fund has one and only one owner. A specific Melon Fund can be canonically referenced by its contract address. The Melon Fund provides the essential functionality for minimalistic investment management: fund accounting, fee calculation, share issuance, custody, security, asset segregation and the division of responsibilities.
5 |
6 | ## Stakeholders
7 |
8 | #### Owner
9 | `owner` in the Solidity context refers to the address retaining special privileges regarding the operation of the smart contract.
10 |
11 | #### Investment Manager
12 | Investment Manager refers to the individual entitled to exercise discretionary portfolio management authority over the assets within the Melon Fund. As defined by the Melon Protocol, the Investment Manager is necessarily also the creator and `owner` of the Melon Fund.
13 |
14 | #### Investor
15 | Investor refers to an individual(s) who have successfully transferred eligible crypto assets, i.e. subscribed, to the Melon Fund through the requestInvestment() mechanism and holding Melon Fund share tokens in their address. Investors' addresses will have a quantity of Melon Fund shares commensurate with their subscription(s).
16 |
17 | ## Actions
18 |
19 | #### Redemption
20 | Redemption refers to an action taken by an Investor invoking the `requestRedemption()` function of the Melon Fund. A successful redemption results in the Investor receiving the Melon Fund NAV proportional to their share quantity at the time of redemption and Investor share tokens will be destroyed. Redemption requests function analogously to a limit sell order, in that the Investor specifies a redemption price, but must wait for two price feed update cycles before the redemption is actually executed. The redemption execution will fail if the portfolio holds insufficient amounts of the redemption asset token or if the price of the redemption asset token has moved below the Investor's redemption request price, i.e. to the detriment of the Investor. Investors can also elect to redeem their pro-rata share of the individual underlying assets in the Melon Fund directly as a "slice" of the fund, i.e. a redemption-in-kind.
21 |
22 | #### Investment/Subscription
23 | Subscriptions refers to an action taken by an Investor invoking the `requestInvestment()` function of the Melon Fund. Subscription requests function analogously to a limit buy order, in that the Investor specifies subscription price, but must wait for two price feed update cycles before the investment is actually executed and accepted by the Melon Fund. The subscription execution will fail if the price of the subscription asset token has moved above the Investor's subscription request price, i.e. to the detriment of the Investor. A successful subscription results in the transfer of Investor subscription asset tokens to the Melon Fund's custody and the Investor receiving the commensurate quantity of newly created Melon Fund share tokens based on the subscribing asset's price and Melon Fund NAV at the time of subscription.
24 |
25 | #### Emergency Redeem
26 | The Emergency Redeem functionality truly embodies the idea that Investors have full, absolute control and custody of their asset tokens at all times.
27 |
28 | #### Trade
29 | Trade is an action that can be undertaken by the Investment Manager where a specific quantity of a given asset held by the Melon Fund is exchanged for another asset via an exchange as specified by the Investment Manager at fund set up.
30 |
31 | #### Version Shutdown
32 | A Version Shutdown is an action which allows anyone to shutdown any individual Melon Fund. All trading, investment/subscription and redemption in the specified redemption asset is disabled. Redemptions are fulfilled only by slice, with Investors receiving their pro-rata share of all underlying token assets in the Melon Fund. A redemption by slice on a shutdown Melon Fund remains the responsibility of the Investor. A Version Shutdown is a high-severity action which is only callable by the Melonport governance multi-signature wallet/Technical Council.
33 |
34 | #### Fund Shutdown
35 | A Fund Shutdown is an action which can be called by the Investment Manager to disable trading, investment/subscription and redemption in the specified redemption asset. Redemptions are fulfilled only by slice, with Investors receiving their pro-rata share of all underlying token assets in the Melon Fund. A redemption by slice on a shutdown Melon Fund remains the responsibility of the Investor.
36 |
37 | ## Terms
38 |
39 | #### Address
40 | Address refers to any valid Ethereum address as defined by the Ethereum Protocol. Addresses consist of 40 hexadecimal characters prefaced with "0x". External addresses are controlled by a user's private key. Smart contract addresses have no knowable private key and are controlled by the functionality defined by the smart contract which generated the address. External addresses are usually generated by a user's wallet.
41 |
42 | #### Exchange
43 | Please refer to the LINK: Exchange section of the documentation.
44 |
45 | #### Decentralized Exchange (DEX)
46 | Please refer to the LINK: Exchange section of the documentation.
47 |
48 | #### Price Feed Operator
49 | Please refer to the LINK: Price Feed section of the documentation.
50 |
51 | #### Technical Council
52 | Technical Council refers to the Melon Protocol governance body which actions governance functions related to critical operational areas of Melon Protocol, such as Price Feed operations, Melon Universe/Asset Registrar maintenance and future protocol development direction. The Technical Council consists of individuals elected by MLN token holders. Please refer to the LINK: Governance section of the documentation.
53 |
54 | #### Slice
55 | A Slice represents a pro-rata share of all individual tokens held in the Melon Fund at the time of redemption request. The Investor will not receive the NAV value of their investment in the investment token, but will receive all individual tokens held by the Melon Fund at the time of redemption transferred to their Investor address.
56 |
57 | #### Shares
58 | An abstraction to facilitate the equitable distribution of ownership of assets in a co-mingled, collective investment fund. Ownership of fund assets is represented by shares in the Melon Fund. The Melon Fund's share price will fluctuate with the market price of the underlying asset tokens held. An Investor buying into the Melon Fund at a specific point in time buys shares at that share price, ensuring that an equitable amount of shares in the Melon Fund are granted. See also: Open-Ended Fund structure.
59 |
60 | #### Melon Price Feed
61 | Please refer to the LINK: Price Feed section of the documentation.
62 |
63 | #### Melon Asset Registrar
64 | Please refer to the LINK: Asset Registrar section of the documentation.
65 |
66 | #### Melon Governance
67 | Please refer to the LINK: Governance section of the documentation.
68 |
69 | #### Melon Risk Engineering
70 | Risk Engineering is a Melon Fund modular smart contract which facilitates the customization of Investment Manager interaction with the Melon Fund. Currently, the Risk Engineering module can verify if a Make Order or Take Order are permitted given the Order price and the Reference Price from the Price Feed. The Risk Engineering functionality will gain a much richer toolset in forthcoming releases, enabling the Investment Manager to demonstrably constrain Investment Manager actions, embedding an ex ante trade discipline and rigor within the Melon Fund's strategy. Please refer to the LINK: Risk Engineering section of the documentation.
71 |
72 | #### Melon Compliance
73 | Compliance is a Melon Fund modular smart contract which facilitates the customization of Investor interaction with the Melon Fund. Currently, the Compliance module can make specific Investor addresses eligible or not eligible for investment, that is an address is either allowed or disallowed to issue an investment request. Redemptions are currently always allowed. For further information on the Compliance module, please refer to the LINK: Compliance section of the documentation.
74 |
75 | #### Custody/Custodian
76 | Custody is a service normally provided to funds in the traditional investment management industry. It is the practice of actually holding and safeguarding assets on behalf of a representative owner, in this case, a fund. A Custodian is a regulated, third party operator of such a service, who is entrusted with holding these assets. Contrary to a legacy fund where the fund is the legal owner of underlying assets held by a third party custodian, the Melon Fund smart contract *is* the Custodian of the fund's token assets, with the Investor having ultimate power of control of Investor assets held within the Melon Fund. At the same time, the Investment Manager has discretionary control over the asset allocation within the Melon Fund.
77 |
78 | #### Administration/Administrator
79 | Administration is a service normally provided to funds in the traditional investment management industry and is usually a legal requirement which an independent, regulated third party must fulfill. There are many facets to fund administration:
80 |
81 | - NAV calculation
82 | - Securities pricing
83 | - Preparation of financial statement, reports, filings, prospectus, etc.
84 | - Fund accountant
85 | - Preparation of filings
86 | - Reconciliation with Custodian and Broker
87 | - Daily trade settlement
88 | - Calculation and payment of fund expenses
89 | - Performance calculation
90 | - Monitoring investment Compliance
91 | - Supervision of liquidation
92 |
93 | In the Melon Fund context, these duties are carried out by transparent, immutable and dispassionate smart contracts running on the Ethereum blockchain infrastructure.
94 |
95 |
96 | #### Audit/Auditor
97 | Auditing is a service normally provided to funds in the traditional investment management industry, and is usually a legal requirement which an independent third party must fulfill. Auditors reconcile and compare books and accounts maintained by various counterparties to a fund such as the manager, custodian and administrator, ensuring correct record-keeping between them. Auditors issue opinions with the weight of their reputation as to the correctness of a fund's state of affairs. In the traditional investment management environment today, a high level of certainty and comfort is provided by multiple independent inspections of fund operations; essentially counterparties monitoring each other. This operational overhead naturally incurs costs which are borne by fund performance. In the Melon Fund and blockchain context, much of this overhead is obviated in that calculations are deterministic and transparent, and the fact that the trade **_IS_** the transfer **_IS_** the settlement **_IS_** the record. That is to say, there is only on canonical source of truth: the very sending of a transaction/transfer **_IS_** the recording of the transaction, rendering comparison and verification superfluous.
98 |
99 | #### Transfer Agent
100 | The Transfer Agent in the traditional investment management industry is an institution which interacts closely with the Registrar in maintaining records and entries for the ownership of securities. Transfer Agents also ensure that interest- or dividend payments are made to the security owners on time. In the Melon Fund and blockchain context, this duty is inherently embedded in the smart contract/blockchain infrastructure of an asset token ledger, and is carried out as a matter of course.
101 |
102 | #### Registrar
103 | The Registrar in the traditional investment management industry is an institution which maintains the record of ownership of securities. In the Melon Fund and blockchain context, this duty is inherently embedded in the smart contract/blockchain infrastructure of an asset token ledger, and is carried out as a matter of course.
104 |
105 | #### Order
106 | An Order is a specification for a desired asset token trade. The specification of the trade enumerates the buy asset, sell asset, buy quantity and buy price. Taken together, these things derive an implicit relative price of one asset in terms of the other. Active Orders explicitly created for- and issued to a specific exchange can be seen as a live instruction to transact the trade as specified.
107 |
108 | #### Make Order
109 | Make Orders are Orders for which no matching analog order exists. That is, Make Orders provide liquidity to the market for the asset token specified. Make Orders will not be executed immediately, but must wait for Investor to take the opposite side of the trade.
110 |
111 | #### Take Orders
112 | Take Orders are Orders which take the opposite side of a currently existing Make Order, agreeing to the specified asset tokens in the specified quantities. Take Orders remove liquidity to the market for the asset token specified.
113 |
114 | #### Order Book
115 | An Order Book is a list of buy- and sell orders maintained by a specific exchange for a specific asset token pair. Once orders are filled, the exchange removes the order from the Order Book. The Order Book essentially describes the demand- and supply curves for a specific asset token in relative terms of another asset token.
116 |
117 | #### Best Price Execution
118 | When in the position of managing the capital of Investors in a fiduciary context, Best Price Execution refers to the practice, of endeavoring to find the most favorable terms for a given trade. The practice seeks to avoid rewarding illicit behavior at the cost of the Investor. In the context of the Melon Fund, Best Price Execution prohibits exchange trades which lie below a specified tolerance threshold to the price feed, which serves as a proxy of the current market price.
119 |
120 | #### Management Fee
121 | Management Fee is the fee charged to the Investor by the Investment Manager for the service of discretionary management of the Melon Fund's assets. The Management Fee is specified as a percentage of the Investor Gross Asset Value (GAV) on a per annum basis. The Management Fee is paid in shares of the Melon Fund. Fee shares are created out of inflating the total supply of Melon Fund shares, achieving the same impact as directly paying fees out of the Melon Fund's underlying token assets, but in a more simple and elegant mechanism that further aligns Investment Manager incentives with Investors.
122 |
123 | #### Performance Fee
124 | Performance Fee is the fee charged to the Investor by the Investment Manager for achieving positive performance in the management of the Melon Fund's assets. The Performance Fee is specified as a percentage of the positive performance achieved over a given time period, i.e. the crystalization period. The Performance Fee is paid in shares of the Melon Fund. Fee shares are created out of inflating the total supply of Melon Fund shares, achieving the same impact as directly paying fees out of the Melon Fund's underlying token assets, but in a more simple and elegant mechanism that further aligns Investment Manager incentives with Investors.
125 |
126 | #### Highwatermark
127 | Highwatermark is the NAV/Share level indicating the highest performance the Melon Fund has achieved since the last fee claim by the Investment Manager. This metric is used to determine the level of performance fees due to the Investment Manager at an given point in time.
128 |
129 | #### Crystalization Period
130 | Crystalization period is the interval of time over which a performance fee, if earned, can duly be collected. Here, earned is taken to mean that the current NAV/Share is higher than the ending NAV/Share level of the previous period for which fees were claimed.
131 |
132 | #### Hurdle
133 | A hurdle is a percentage figure indicating a positive performance amount below which performance fees will not be charged. Performance exceeding the hurdle rate will be charged as specified under [Performance Fee](#performancefee). Hurdle functionality in Melon Fund performance measurement is not yet implemented.
134 |
135 | #### Breach
136 | A breach occurs when a specific measurement exceeds a defined threshold.
137 |
138 | #### Stake
139 | Stake is a form of security deposit held by a smart contract and used to incentivize desired behavior. When observed behavior in contrast to specified behavior is detected, the smart contract has the ability to burn all, or a portion of the staked security deposit.
140 |
141 | #### Open-Ended Fund
142 | An Open-Ended Fund is a fund structure which places no upper limit on the amount which can be invested. As capital enters the Open-Ended Fund, new shares are created commensurate with the current NAV of the fund and the amount of capital invested. As investment capital leaves the fund through redemptions, the representative shares are destroyed, commensurate with the redemption amount.
143 |
144 | #### Token
145 | A Token is a symbolic representation of a unitized measure in a cryptographic decentralized ledger system. Token ownership (or control) resides exclusively with a cryptographic address and can only be transferred (or interacted with) by the use of the private key belonging to the holding address. The private key is used to create a cryptographically-signed transaction which is submitted to the blockchain network, which in turn executes the instructions specified therein.
146 |
147 | #### ERC20 Standard
148 | The ERC20 Standard is a standardized token interface which specifies certain functionsand events, which when implemented, allow a token to interact with other tokens and infrastructure smart contracts. See [ERC20 Token Standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md).
149 |
150 | #### Ethereum
151 | The Ethereum blockchain is a blockchain network which implements smart contract allowing the user to specify how state may change. Ethereum is the foundation for many decentralized applications including the Melon Protocol and Melon Funds, as well as all asset tokens traded and held in Melon Funds.
152 |
153 | #### Blockchain
154 | A Blockchain is a general purpose technology which can store data in a decentralized and immutable way. The storage and maintenance of the data is incentivized by the internal issuance of a blockchain-native token of value.
155 |
156 | #### Transaction
157 | A Transaction is a transfer of tokens/value from one cryptographic account to another or the calling of a function on a smart contract to affect some behavior on the part of the called smart contract. In some cases, a smart contract function call can also include the transfer of tokens/value.
158 |
159 | #### NAV
160 | The NAV is the Net Asset Value of the Melon Fund.
161 | The price of a fund is quoted on a per-share basis, i.e. NAV/Share. The NAV will fluctuate with the market price of the underlying holdings of the fund. Market prices are represented by the Canonical Price Feed providing a periodic valuation of the fund assets. Net Asset Value is value of net long positions in the portfolio less any credit positions (e.g. leverage) less any fees due. Currently Melon Funds can only hold long exposure positions and cannot implement leverage. This means that the NAV will be the GAV less unclaimed fees at a given point in time.
162 |
163 | #### GAV
164 | The GAV is the Gross Asset Value of the Melon Fund. The GAV will fluctuate with the market price of the underlying holdings of the fund. Market prices are represented by the Canonical Price Feed providing a periodic valuation of the fund assets. The GAV represents the current market value of the Melon Fund before the consideration of any fees due at a given point in time.
165 |
166 | #### Investment/Subscription Asset
167 | The Investment/Subscription Asset is the token asset defined by the Investment Manager with which Investors may invest or subscribe to the Melon Fund.
168 |
169 | #### Redemption Asset
170 | The Redemption Asset is the token asset defined by the Investment Manager in which Investors may redeem from the Melon Fund.
171 |
172 | #### Quote Asset
173 | The Quote Asset is the asset in which the Melon Fund is valued. The Quote Asset is specified by the Investment Manager at the time of the Melon Fund's set up.
174 |
175 | #### Native Asset
176 | The Native Asset is the token asset used by a blockchain for internal accounting, incentivization and transaction fee payment. The Native Asset on the Ethereum blockchain network is Ether (ETH).
177 |
178 |
179 | #### Base Asset
180 | TBD
181 |
182 | #### Reference Asset
183 | TBD
184 |
185 | #### Allocate vs Invest
186 |
187 | Allocate: The Investment Manager chooses and trades for specific assets within the fund. Allocation is the only discretionary power with the Investment Manager regarding the Melon Fund's underlying holdings.
188 |
189 | Invest: The Investor transfers tokens to the Melon Fund. Technically, the Melon Fund also invests into the underlying holdings; this underscores the fact that the underlying holdings' ownership is completely segregated from the Investment Manager and resided with the Melon Fund smart contract, and ultimately, with the Investor.
190 |
--------------------------------------------------------------------------------
/chapters/exchanges.md:
--------------------------------------------------------------------------------
1 | # Exchange Adapters
2 |
3 | ## General
4 |
5 | Exchanges are each integrated into the Melon protocol through exchange adapter contracts. Exchange adapter contracts each inherit from the standard contract ExchangeAdapter.sol. Each adapter then maps this functionality to the specific exchange contract's defined functionality, overriding the base contract's public methods.
6 |
7 |
8 | ## ExchangeAdapter.sol
9 |
10 | #### Description
11 |
12 | The ExchangeAdapter contract intended to generalize the implementation of any concrete exchange adapter.
13 |
14 | The function parameter signatures for the functions `makeOrder()`, `takeOrder()` and `cancelOrder()` are identical. The parameters are summarized here:
15 |
16 | `address targetExchange` - The address of the intended exchange contract pertaining to the order.
17 |
18 | `address[6] orderAddresses` - An array containing address pertaining as per below to the order.
19 | `orderAddresses[0]` - The address of the order maker.
20 | `orderAddresses[1]` - The address of the order taker.
21 | `orderAddresses[2]` - The address of the maker asset token contract.
22 | `orderAddresses[3]` - The address of the taker asset token contract.
23 | `orderAddresses[4]` - The address of the fee recipient, `feeRecipientAddress`.
24 | `orderAddresses[5]` - The address of the sender, `msg.sender`.
25 |
26 | `uint[8] orderValues` - An array containing values pertaining as per below to the order.
27 | `orderValues[0]` - The maker asset quantity.
28 | `orderValues[1]` - The taker asset quantity.
29 | `orderValues[2]` - The maker fee.
30 | `orderValues[3]` - The taker fee.
31 | `orderValues[4]` - The expiration time of the order in seconds.
32 | `orderValues[5]` - The salt/nonce used to differentiate orders of like assets and quantities.
33 | `orderValues[6]` - The order fill quantity, i.e. the quantity of the taker asset token traded.
34 | `orderValues[7]` - The signature mode specific to the Dexy exchange.
35 |
36 | `bytes32 identifier` - The order identifier.
37 |
38 | `bytes makerAssetData` - Encoded data specific to the maker asset.
39 |
40 | `bytes takerAssetData` - Encoded data specific to the taker asset.
41 |
42 | `bytes signature` - The signature of the order maker.
43 |
44 |
45 | #### Inherits from
46 |
47 | None.
48 |
49 |
50 |
51 | #### On Construction
52 |
53 | None.
54 |
55 |
56 |
57 | #### Structs
58 |
59 | None.
60 |
61 |
62 |
63 | #### Enums
64 |
65 | None.
66 |
67 |
68 |
69 | #### Modifiers
70 |
71 | `modifier onlyManager()`
72 |
73 | This function modifier requires that `msg.sender` is the fund manager address prior to executing functionality.
74 |
75 |
76 | `modifier notShutDown()`
77 |
78 | This function modifier requires that the fund is not in a shut down state prior to executing functionality.
79 |
80 |
81 | `modifier onlyCancelPermitted(address exchange, address asset)`
82 |
83 | This function modifier requires that either `msg.sender` is the fund manager address, the fund is in a shut down state or the order has expired prior to executing functionality.
84 |
85 |
86 | #### Events
87 |
88 | None.
89 |
90 |
91 |
92 | #### Public State Variables
93 |
94 | None.
95 |
96 |
97 |
98 | #### Functions
99 |
100 | `function getTrading() internal view returns (Trading)`
101 |
102 | This internal view function returns the current contracts address as a `Trading` contract.
103 |
104 |
105 | `function getHub() internal view returns (Hub)`
106 |
107 | This internal view function returns the `Hub` contract corresponding to the `Trading` contract.
108 |
109 |
110 | `function getAccounting() internal view returns (Accounting)`
111 |
112 | This internal view function returns the `Accounting` contract corresponding to the current `Hub` contract.
113 |
114 |
115 | `function hubShutDown() internal view returns (bool)`
116 |
117 | This internal view function returns a boolean indicating the current shut down state of the fund.
118 |
119 |
120 | `function getManager() internal view returns (address)`
121 |
122 | This internal view function returns the address of the current fund's fund manager.
123 |
124 |
125 | `function ensureNotInOpenMakeOrder(address _asset) internal view`
126 |
127 | This internal view function ensures that no open make order currently exists for the asset token address provided.
128 |
129 |
130 | `function makeOrder(
131 | address targetExchange,
132 | address[6] orderAddresses,
133 | uint[8] orderValues,
134 | bytes32 identifier,
135 | bytes makerAssetData,
136 | bytes takerAssetData,
137 | bytes signature)`
138 |
139 | This public function must ensure that:
140 |
141 | the fund is not shut down,
142 | the asset token prices are recent,
143 | applicable risk policies are evaluated,
144 | asset tokens to be traded are approved (if required),
145 | the make order transaction is sent to the exchange contract,
146 | the order is registered on the exchange contract (if possible),
147 | the acquired asset token, if not already held, is added to `ownedAssets`.
148 |
149 | The function creates a make order on a specific exchange specifying the asset tokens to exchange and the corresponding quantities (implicit price) required for the order. The function on the base contract remains unimplemented and reverts.
150 |
151 |
152 | `function takeOrder(
153 | address targetExchange,
154 | address[6] orderAddresses,
155 | uint[8] orderValues,
156 | bytes32 identifier,
157 | bytes makerAssetData,
158 | bytes takerAssetData,
159 | bytes signature)`
160 |
161 | This public function must ensure that:
162 |
163 | the fund is not shut down,
164 | the fund is not filling its own make order,
165 | the asset token price pair exists in the price source,
166 | the asset token prices are recent,
167 | applicable risk policies are evaluated,
168 | asset tokens to be traded are approved (if required),
169 | the take order transaction is sent to the exchange contract,
170 | the order is removed from the exchange contract (if possible),
171 | the acquired asset token, if not already held, is added to `ownedAssets`.
172 |
173 | The function takes the opposite side of an existing make order on a specific exchange, delivering the asset token demanded by the make order in exchange for the asset token supplied by the make order, in the quantities (or less for partial order fills) specified. The function on the base contract remains unimplemented and reverts.
174 |
175 |
176 | `function cancelOrder(
177 | address targetExchange,
178 | address[6] orderAddresses,
179 | uint[8] orderValues,
180 | bytes32 identifier,
181 | bytes makerAssetData,
182 | bytes takerAssetData,
183 | bytes signature)`
184 |
185 | This function must ensure that:
186 |
187 | the `msg.sender` is the order owner or the order has expired or the fund is shut down,
188 | the order is removed from the fund-internal order-tracking array,
189 | the order on the exchange is canceled.
190 |
191 | The function cancels and removes all order information within the fund and on the exchange where it existed. The function on the base contract remains unimplemented and reverts.
192 |
193 |
194 | `function getOrder(
195 | address onExchange,
196 | uint id,
197 | address makerAsset)
198 | view returns (
199 | address,
200 | address,
201 | uint,
202 | uint)`
203 |
204 | This public view function is meant to return the relevant order information (maker asset token address, taker asset token address, maker asset token quantity and taker asset token quantity) given the exchange contract address, the order identifier and the maker asset token contract address parameters. The function on the base contract remains unimplemented and reverts.
205 |
206 |
207 | ## EngineAdapter.sol
208 |
209 | #### Description
210 |
211 | This contract is the exchange adapter to the Melon Engine and serves as the interface from a Melon fund to the Melon Engine for the express purposes of the Melon fund trading MLN to the Melon Engine in exchange for WETH.
212 |
213 |
214 | #### Inherits from
215 |
216 | DSMath, TokenUser, ExchangeAdapter (link)
217 |
218 |
219 |
220 | #### On Construction
221 |
222 | None.
223 |
224 |
225 |
226 | #### Structs
227 |
228 | None.
229 |
230 |
231 |
232 | #### Enums
233 |
234 | None.
235 |
236 |
237 |
238 | #### Modifiers
239 |
240 | None.
241 |
242 |
243 |
244 | #### Events
245 |
246 | None.
247 |
248 |
249 |
250 | #### Public State Variables
251 |
252 | None.
253 |
254 |
255 |
256 | #### Public Functions
257 |
258 | `function takeOrder (
259 | address targetExchange,
260 | address[6] orderAddresses,
261 | uint[8] orderValues,
262 | bytes32 identifier,
263 | bytes makerAssetData,
264 | bytes takerAssetData,
265 | bytes signature)
266 | onlyManager notShutDown`
267 |
268 | The following parameters are used by the function:
269 |
270 | `targetExchange` - The address of the Melon Engine exchange contract.
271 | `orderAddresses[2]` - The address of the WETH token contract (maker asset token).
272 | `orderAddresses[3]` - The address of the MLN token contract (taker asset token).
273 | `orderValues[0]` - The min quantity of ETH to get back from the Engine.
274 | `orderValues[1]` - The quantity of the MLN token, expressed in 18 decimal precision.
275 | `orderValues[6]` - Same as orderValues[1].
276 |
277 | This function requires that the `msg.sender` is the fund manager and that the fund is not shut down. The function then requires that desired MLN token trade quantity be approved by the Melon fund. The function calls the Melon Engine to get the corresponding quantity of ETH. The Melon Engine function `sellAndBurnMln` is called, as the fund transfers MLN for WETH, as the WETH is received by the Melon fund and transferred to the Melon fund's vault, `ownedAssets` is updated with the new position if required and finally, the order status is updated.
278 |
279 |
280 | ## ZeroExV2Adapter.sol
281 |
282 | #### Description
283 |
284 | This contract is the exchange adapter to the 0x v2 Exchange contract and serves as the interface from a Melon fund to the 0x v2 Exchange for purposes of exchange of asset tokens listed on the 0x v2 Exchange.
285 |
286 |
287 | #### Inherits from
288 |
289 | ExchangeAdapter, DSMath (link)
290 |
291 |
292 |
293 | #### On Construction
294 |
295 | None.
296 |
297 |
298 |
299 | #### Structs
300 |
301 | None.
302 |
303 |
304 |
305 | #### Enums
306 |
307 | None.
308 |
309 |
310 |
311 | #### Modifiers
312 |
313 | None.
314 |
315 |
316 |
317 | #### Events
318 |
319 | None.
320 |
321 |
322 |
323 | #### Public State Variables
324 |
325 | None.
326 |
327 |
328 |
329 | #### Public Functions
330 |
331 | `function makeOrder(
332 | address targetExchange,
333 | address[6] orderAddresses,
334 | uint[8] orderValues,
335 | bytes32 identifier,
336 | bytes wrappedMakerAssetData,
337 | bytes takerAssetData,
338 | bytes signature
339 | ) onlyManager notShutDown`
340 |
341 | Please see parameter descriptions above.
342 |
343 | This public function requires that the `msg.sender` is the fund manager and that the fund is not shut down. The function creates a make order on the 0x v2 exchange contract. It ensures that the maker asset token is not currently listed in any other open make order the Melon fund may have on any exchange. The taker asset token is preliminarily added to the Melon fund's owned assets and an open make order is added to the Melon fund's internal order tracking. Finally, the order is pre-signed on the 0x v2 exchange contract authorizing manager's signature on behalf of the trading contract.
344 |
345 |
346 | `function cancelOrder(
347 | address targetExchange,
348 | address[6] orderAddresses,
349 | uint[8] orderValues,
350 | bytes32 identifier,
351 | bytes wrappedMakerAssetData,
352 | bytes takerAssetData,
353 | bytes signature
354 | ) onlyCancelPermitted(targetExchange, orderAddresses[2])`
355 |
356 | Please see parameter descriptions above.
357 |
358 | This public function cancels an existing order on the 0x v2 exchange contract by calling the 0x v2 exchange contract's `cancelOrder()` function. The function applies the `onlyCancelPermitted` modifier, allowing the cancel to only be submitted under one of these conditions: the fund manager cancels the order, the fund is shut down or the order has expired. The asset token is finally removed from the Melon fund's internal order tracking.
359 |
360 |
361 | `function getOrder(
362 | address onExchange,
363 | uint id,
364 | address makerAsset)
365 | view returns (
366 | address,
367 | address,
368 | uint,
369 | uint)`
370 |
371 | This public view function returns the relevant order information (maker asset token address, taker asset token address, maker asset token quantity and taker asset token quantity) given the exchange contract address, the order identifier and the maker asset token contract address parameters. The function can determine whether the order has been partially or fully filled (returning the remaining maker asset token quantity and the remaining taker asset token quantity)
372 |
373 |
374 | `function approveTakerAsset(
375 | address targetExchange,
376 | address takerAsset,
377 | bytes takerAssetData,
378 | uint fillTakerQuantity)
379 | internal`
380 |
381 | This internal view function withdraws fillTakerQuantity amount of the taker asset from the vault and approves the same amount to the asset proxy
382 |
383 |
384 | `function approveMakerAsset(
385 | address targetExchange,
386 | address makerAsset,
387 | bytes makerAssetData,
388 | uint makerQuantity)
389 | internal`
390 |
391 | This internal view function withdraws makerQuantity amount of the maker asset from the vault and approves the same amount amount to the asset proxy
392 |
393 |
394 | `function constructOrderStruct(
395 | address[6] orderAddresses,
396 | uint[8] orderValues,
397 | bytes makerAssetData,
398 | bytes takerAssetData)
399 | internal
400 | view
401 | returns (LibOrder.Order memory order)`
402 |
403 | This internal view function returns a populated `order` struct based on the parameter values provided.
404 |
405 |
406 | `function getAssetProxy(
407 | address targetExchange,
408 | bytes assetData)
409 | internal
410 | view
411 | returns (address assetProxy)`
412 |
413 | This internal view function returns the address of the asset proxy given the address of the Ethfinex exchange contract and asset data provided.
414 |
415 |
416 | `function getAssetAddress(
417 | bytes assetData)
418 | internal
419 | view
420 | returns (address assetAddress)`
421 |
422 | This internal view function returns the address of the asset given the asset data provided.
423 |
424 |
425 | ## EthfinexAdapter.sol
426 |
427 | #### Description
428 |
429 | This contract is the exchange adapter to the Ethfinex Exchange contract and serves as the interface from a Melon fund to the Ethfinex Exchange for purposes of exchange of asset tokens listed on the Ethfinex Exchange.
430 |
431 |
432 | #### Inherits from
433 |
434 | ExchangeAdapter, DSMath, DBC (link)
435 |
436 |
437 |
438 | #### On Construction
439 |
440 | None.
441 |
442 |
443 |
444 | #### Structs
445 |
446 | None.
447 |
448 |
449 |
450 | #### Enums
451 |
452 | None.
453 |
454 |
455 |
456 | #### Modifiers
457 |
458 | None.
459 |
460 |
461 |
462 | #### Events
463 |
464 | None.
465 |
466 |
467 |
468 | #### Public State Variables
469 |
470 | None.
471 |
472 |
473 |
474 | #### Public Functions
475 |
476 | `function makeOrder(
477 | address targetExchange,
478 | address[6] orderAddresses,
479 | uint[8] orderValues,
480 | bytes32 identifier,
481 | bytes wrappedMakerAssetData,
482 | bytes takerAssetData,
483 | bytes signature
484 | ) onlyManager notShutDown`
485 |
486 | Please see parameter descriptions above.
487 |
488 | This public function requires that the `msg.sender` is the fund manager and that the fund is not shut down. The function creates a make order on the Ethfinex exchange contract. It ensures that the maker asset token is not currently listed in any other open make order the Melon fund may have on any exchange. The function signs the order and ensures the signature is valid. The taker asset token is preliminarily added to the Melon fund's owned assets and an open make order is added to the Melon fund's internal order tracking. Finally, the order is added to the Ethfinex exchange contract.
489 |
490 |
491 | `function cancelOrder(
492 | address targetExchange,
493 | address[6] orderAddresses,
494 | uint[8] orderValues,
495 | bytes32 identifier,
496 | bytes wrappedMakerAssetData,
497 | bytes takerAssetData,
498 | bytes signature
499 | ) onlyCancelPermitted(targetExchange, orderAddresses[2])`
500 |
501 | Please see parameter descriptions above.
502 |
503 | This public function cancels an existing order on the Ethfinex exchange contract by calling the Ethfinex exchange contract's `cancelOrder()` function. The function applies the `onlyCancelPermitted` modifier, allowing the cancel to only be submitted under one of these conditions: the fund manager cancels the order, the fund is shut down or the order has expired. The asset token is finally removed from the Melon fund's internal order tracking.
504 |
505 |
506 | `function withdrawTokens(
507 | address targetExchange,
508 | address[6] orderAddresses,
509 | uint[8] orderValues,
510 | bytes32 identifier,
511 | bytes makerAssetData,
512 | bytes takerAssetData,
513 | bytes signature)`
514 |
515 | Please see parameter descriptions above.
516 |
517 | This public function withdraws all asset tokens held by the Ethfinex exchange in open make orders, then removes the make order form the Melon fund's internal order tracking by calling the Trading contract's `removeOpenMakeOrder()`. Finally, the function returns the asset tokens to the vault and adds the asset token to `ownedAssets`.
518 |
519 |
520 | `function getOrder(
521 | address onExchange,
522 | uint id,
523 | address makerAsset)
524 | view returns (
525 | address,
526 | address,
527 | uint,
528 | uint)`
529 |
530 | This public view function returns the relevant order information (maker asset token address, taker asset token address, maker asset token quantity and taker asset token quantity) given the exchange contract address, the order identifier and the maker asset token contract address parameters. The function can determine whether the order has been partially or fully filled (returning the remaining maker asset token quantity and the remaining taker asset token quantity)
531 |
532 |
533 |
534 | `function wrapMakerAsset(
535 | address targetExchange,
536 | address makerAsset,
537 | bytes wrappedMakerAssetData,
538 | uint makerQuantity,
539 | uint orderExpirationTime)
540 | internal`
541 |
542 | This internal function withdraws the maker asset token from the Melon fund's vault, wrapping the maker token according to Ethfinex's wrapper registry.
543 |
544 |
545 | `function constructOrderStruct(
546 | address[6] orderAddresses,
547 | uint[8] orderValues,
548 | bytes makerAssetData,
549 | bytes takerAssetData)
550 | internal
551 | view
552 | returns (LibOrder.Order memory order)`
553 |
554 | This internal view function returns a populated `order` struct based on the parameter values provided.
555 |
556 |
557 | `function getAssetProxy(
558 | address targetExchange,
559 | bytes assetData)
560 | internal
561 | view
562 | returns (address assetProxy)`
563 |
564 | This internal view function returns the address of the asset proxy given the address of the Ethfinex exchange contract and asset data provided.
565 |
566 |
567 | `function getAssetAddress(
568 | bytes assetData)
569 | internal
570 | view
571 | returns (address assetAddress)`
572 |
573 | This internal view function returns the address of the asset given the asset data provided.
574 |
575 |
576 | `function getWrapperToken(
577 | address token)
578 | internal
579 | view
580 | returns (address wrapperToken)`
581 |
582 | This internal view function returns the address of the Ethfinex-specified wrapped asset token contract given the address of asset token contract provided.
583 |
584 |
585 | ## KyberAdapter.sol
586 |
587 | #### Description
588 |
589 | This contract is the exchange adapter to the Kyber Network contract and serves as the interface from a Melon fund to the Kyber Network contract for purposes of exchange of asset tokens listed on the Kyber Network.
590 |
591 |
592 | #### Inherits from
593 |
594 | ExchangeAdapter, DSMath, DBC (link)
595 |
596 |
597 |
598 | #### On Construction
599 |
600 | None.
601 |
602 |
603 |
604 | #### Structs
605 |
606 | None.
607 |
608 |
609 |
610 | #### Enums
611 |
612 | None.
613 |
614 |
615 |
616 | #### Modifiers
617 |
618 | None.
619 |
620 |
621 |
622 | #### Events
623 |
624 | None.
625 |
626 |
627 |
628 | #### Public State Variables
629 |
630 | `address public constant ETH_TOKEN_ADDRESS = 0x00eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`
631 |
632 | This public constant state variable represents the ETH token address.
633 |
634 |
635 | #### Public Functions
636 |
637 | `function takeOrder(
638 | address targetExchange,
639 | address[6] orderAddresses,
640 | uint[8] orderValues,
641 | bytes32 identifier,
642 | bytes makerAssetData,
643 | bytes takerAssetData,
644 | bytes signature)
645 | onlyManager notShutDown`
646 |
647 | Please see parameter descriptions above. In the context of the Kyber exchange contract's nomenclature (swapToken() function), the following parameters take the specified mappings:
648 |
649 | `orderAddresses[2]` - The Src token address.
650 | `orderAddresses[3]` - The Dest token address.
651 | `orderValues[0]` - The Src token quantity.
652 | `orderValues[1]` - The Dest token quantity.
653 |
654 | This public function must ensure that:
655 |
656 | the fund is not shut down,
657 | the `msg.sender` is the fund manager.
658 | take fill quantity is equal to the taker asset quantity,
659 | the asset token prices are recent and calculate the minimum required exchange rate,
660 | applicable risk policies are evaluated,
661 | asset tokens to be traded are approved (if required),
662 | the swap order on the Kyber exchange contract is performed,
663 | the acquired asset token, if not already held, is added to `ownedAssets`. Finally, the acquired asset tokens are returned to the Melon fund's vault and the order status is updated.
664 |
665 | Finally, the function returns acquired token assets to the fund's vault and updates the fund's internal order tracking.
666 |
667 |
668 | `function dispatchSwap(
669 | address targetExchange,
670 | address srcToken,
671 | uint srcAmount,
672 | address destToken,
673 | uint minRate)
674 | internal
675 | returns (uint actualReceiveAmount)`
676 |
677 | This internal function routes the call logic depending on the asset tokens involved. The three possibilities are:
678 |
679 | Fund trades ETH for other asset token - call made to `swapNativeAssetToToken()`
680 | Fund trades other asset token for ETH - call made to `swapTokenToNativeAsset()`
681 | Fund trades non-ETH tokens - call made to `swapTokenToToken()`
682 |
683 | The function takes the following parameters:
684 |
685 | `targetExchange` - The address of the intended exchange contract (i.e. the Kyber Network).
686 | `srcToken` - The address of the asset token the fund will deliver.
687 | `srcAmount` - The quantity of delivering asset token.
688 | `destToken` - The address of the asset token the fund will receive.
689 | `minRate` - The minimum acceptable quantity of the receiving asset token.
690 |
691 | The function returns the quantity of the asset token to be received by the fund.
692 |
693 |
694 | `function swapNativeAssetToToken(
695 | address targetExchange,
696 | address nativeAsset,
697 | uint srcAmount,
698 | address destToken,
699 | uint minRate)
700 | internal
701 | returns (uint receivedAmount)`
702 |
703 | This internal function initiates the trade where the Melon fund delivers ETH for the receiving asset token specified by the `destToken` address parameter. The function withdraws the specified quantity of ETH from the fund's vault sends the ETH quantity to the Kyber Network exchange contract calling its `swapEtherToToken()` function.
704 |
705 | The function takes the following parameters:
706 |
707 | `targetExchange` - The address of the intended exchange contract (i.e. the Kyber Network).
708 | `nativeAsset` - The address of the native asset token the fund will deliver, ETH.
709 | `srcAmount` - The quantity of delivering asset token.
710 | `destToken` - The address of the asset token the fund will receive.
711 | `minRate` - The minimum acceptable quantity of the receiving asset token. If `minRate` is not defined, the expected rate form the Kyber Network is used.
712 |
713 | The function returns the quantity of the `destToken` received. The Kyber Network contract function transfers the asset to this (adapter) contract, where it is then transferred back to the vault in the `takeOrder` function.
714 |
715 |
716 | `function swapTokenToNativeAsset(
717 | address targetExchange,
718 | address srcToken,
719 | uint srcAmount,
720 | address nativeAsset,
721 | uint minRate)
722 | internal
723 | returns (uint receivedAmount)`
724 |
725 | This internal function initiates the trade where the Melon fund delivers the asset token specified by the `srcToken` address parameter for receiving ETH. The function withdraws the specified quantity of the delivery asset token from the fund's vault and sends the quantity to the Kyber Network exchange contract calling its `swapTokenToEther()` function. The function then approves the transfer quantity for the exchange. Finally, the function converts any ETH received to WETH.
726 |
727 | The function takes the following parameters:
728 |
729 | `targetExchange` - The address of the intended exchange contract (i.e. the Kyber Network).
730 | `srcToken` - The address of the asset token the fund will deliver.
731 | `srcAmount` - The quantity of delivering asset token.
732 | `nativeAsset` - The address of the native asset token the fund will receive, ETH.
733 | `minRate` - The minimum acceptable quantity of the receiving asset token.
734 |
735 | The function returns the quantity of the `nativeAsset` received, ETH. The Kyber Network contract function transfers the asset to this (adapter) contract, where it is then transferred back to the vault in the `takeOrder` function.
736 |
737 |
738 | `function swapTokenToToken(
739 | address targetExchange,
740 | address srcToken,
741 | uint srcAmount,
742 | address destToken,
743 | uint minRate)
744 | internal
745 | returns (uint receivedAmount)`
746 |
747 | This internal function initiates the trade where the Melon fund delivers the asset token specified by the `srcToken` address parameter for receiving the asset token specified by the `destToken` address parameter. The function withdraws the specified quantity of the delivery asset token from the fund's vault and sends the quantity to the Kyber Network exchange contract calling its `swapTokenToToken()` function. The function then approves the transfer quantity for the exchange. Finally, the function converts any ETH received to WETH.
748 |
749 | The function takes the following parameters:
750 |
751 | `targetExchange` - The address of the intended exchange contract (i.e. the Kyber Network).
752 | `srcToken` - The address of the asset token the fund will deliver.
753 | `srcAmount` - The quantity of delivering asset token.
754 | `destToken` - The address of the asset token the fund will receive.
755 | `minRate` - The minimum acceptable quantity of the receiving asset token (`destToken`). If `minRate` is not defined, the expected rate form the Kyber Network is used.
756 |
757 | The function returns the quantity of the `destToken` received. The Kyber Network contract function transfers the asset to this (adapter) contract, where it is then transferred back to the vault in the `takeOrder` function.
758 |
759 |
760 | `function calcMinRate(
761 | address srcToken,
762 | address destToken,
763 | uint srcAmount,
764 | uint destAmount)
765 | internal
766 | view
767 | returns (uint minRate)`
768 |
769 | This internal view function returns the minimum acceptable exchange quantity for the taker asset token from the price feed given the following parameters:
770 |
771 | `srcToken` - The address of the asset token the fund will deliver.
772 | `destToken` - The address of the asset token the fund will receive.
773 | `srcAmount` - The quantity of delivering asset token.
774 | `destAmount` - The quantity of receiving asset token.
775 |
776 |
777 | ## MatchingMarketAdapter.sol
778 |
779 | #### Description
780 |
781 | This contract is the exchange adapter to the OasisDex Matching Market exchange contract and serves as the interface from a Melon fund to the OasisDex Matching Market for purposes of exchange of asset tokens listed on the OasisDex Matching Market.
782 |
783 |
784 | #### Inherits from
785 |
786 | ExchangeAdapter, DSMath (link)
787 |
788 |
789 |
790 | #### On Construction
791 |
792 | None.
793 |
794 |
795 |
796 | #### Structs
797 |
798 | None.
799 |
800 |
801 |
802 | #### Enums
803 |
804 | None.
805 |
806 |
807 |
808 | #### Modifiers
809 |
810 | None.
811 |
812 |
813 |
814 | #### Events
815 |
816 | `event OrderCreated(uint id)`
817 |
818 | This event is emitted when a make order is created on the exchange contract. The event logs and broadcasts the order's identifier.
819 |
820 |
821 |
822 | #### Public State Variables
823 |
824 | None.
825 |
826 |
827 |
828 | #### Public Functions
829 |
830 | `function makeOrder(
831 | address targetExchange,
832 | address[6] orderAddresses,
833 | uint[8] orderValues,
834 | bytes32 identifier,
835 | bytes makerAssetData,
836 | bytes takerAssetData,
837 | bytes signature)
838 | onlyManager notShutDown`
839 |
840 | Please see parameter descriptions above.
841 |
842 | This public function must ensure that:
843 |
844 | the fund is not shut down,
845 | the `msg.sender` is the fund manager.
846 | the asset token prices are recent,
847 | applicable risk policies are evaluated,
848 | asset tokens to be traded are approved (if required),
849 | the make order transaction is sent to the exchange contract,
850 | the order is registered on the exchange contract (if possible),
851 | the acquired asset token, if not already held, is added to `ownedAssets`.
852 |
853 | The function creates a make order on the OasisDex Matching Market exchange contract specifying the asset tokens to exchange and the corresponding quantities (implicit price) required for the order.
854 | An `orderID > 0` signifies that the order was successfully submitted to the OasisDex Matching Market exchange contract and the open make order is added to the Melon fund's internal order tracking. Finally, the function emits the `OrderCreated()` with the order's `orderID`.
855 |
856 |
857 | `function takeOrder(
858 | address targetExchange,
859 | address[6] orderAddresses,
860 | uint[8] orderValues,
861 | bytes32 identifier,
862 | bytes makerAssetData,
863 | bytes takerAssetData,
864 | bytes signature)
865 | onlyManager notShutDown`
866 |
867 | Please see parameter descriptions above. Of note are the parameters:
868 |
869 | `orderValues[6]` - The fill quantity of taker asset token.
870 | `identifier` - The active order's orderID.
871 |
872 | This public function must ensure that:
873 |
874 | the fund is not shut down,
875 | the `msg.sender` is the fund manager.
876 | the fund is not filling its own make order,
877 | the asset token price pair exists in the price source,
878 | the asset token prices are recent,
879 | applicable risk policies are evaluated,
880 | asset tokens to be traded are approved (if required),
881 | the take order transaction is sent to the exchange contract,
882 | the order is removed from the exchange contract (if possible),
883 | the acquired asset token, if not already held, is added to `ownedAssets`.
884 |
885 | The function takes the opposite side of an existing make order on the OasisDex Matching Market exchange contract, delivering the asset token demanded by the make order in exchange for the asset token supplied by the make order, in the quantities (or less for partial order fills) specified. Finally, the function returns acquired token assets to the fund's vault and updates the fund's internal order tracking.
886 |
887 |
888 | `function cancelOrder(
889 | address targetExchange,
890 | address[6] orderAddresses,
891 | uint[8] orderValues,
892 | bytes32 identifier,
893 | bytes wrappedMakerAssetData,
894 | bytes takerAssetData,
895 | bytes signature
896 | ) onlyCancelPermitted(targetExchange, orderAddresses[2])`
897 |
898 | Please see parameter descriptions above. Of note are the parameters:
899 |
900 | `orderAddresses[2]` - The order maker asset token.
901 | `identifier` - The active order's orderID.
902 |
903 | This public function cancels an existing order on the OasisDex Matching Market exchange contract by calling the OasisDex Matching Market contract's `cancel()` function. The function applies the `onlyCancelPermitted` modifier, allowing the cancel to only be submitted under one of these conditions: the fund manager cancels the order, the fund is shut down or the order has expired. The asset token is finally removed from the Melon fund's internal order tracking and the maker asset token is returned to the Melon fund's vault.
904 |
905 |
906 | `function getOrder(
907 | address targetExchange,
908 | uint id,
909 | address makerAsset)
910 | view returns (
911 | address,
912 | address,
913 | uint,
914 | uint)`
915 |
916 | This public view function returns the current relevant order information (maker asset token address, taker asset token address, maker asset token quantity and taker asset token quantity) given the exchange contract address, the order identifier and the maker asset token contract address parameters. Orders which have been partially filled will return the remaining, respective token quantities.
917 |
918 |
--------------------------------------------------------------------------------
/chapters/factory.md:
--------------------------------------------------------------------------------
1 | # Factory
2 |
3 | ## General
4 |
5 | Factory contracts are utilities for the creation of the many component contracts and infrastructure providing services to Melon funds.
6 |
7 |
8 | ## Factory.sol
9 |
10 | #### Description
11 |
12 | The contract is a base contract which defines base elements below. It is inherited by all factory contracts.
13 |
14 |
15 | #### Inherits from
16 |
17 | None.
18 |
19 |
20 | #### On Construction
21 |
22 | None.
23 |
24 |
25 |
26 | #### Structs
27 |
28 | None.
29 |
30 |
31 |
32 | #### Enums
33 |
34 | None.
35 |
36 |
37 |
38 | #### Modifiers
39 |
40 | None.
41 |
42 |
43 |
44 | #### Events
45 |
46 | `event NewInstance()`
47 |
48 | `address indexed hub` - The address of the `hub` corresponding to the created contract.
49 | `address indexed instance) - The address of the created contract.
50 |
51 | This event is triggered when a the Factory creates a new contract. The parameters listed above are logged with the event.
52 |
53 |
54 | #### Public State Variables
55 |
56 | `mapping (address => bool) public childExists`
57 |
58 | This public mapping state variable maps an address to boolean. It is used to determine whether an address is that of a contract created by the Factory.
59 |
60 |
61 | #### Public Functions
62 |
63 | `function isInstance(address _child) public view returns (bool)`
64 |
65 | This public view function returns a boolean indicating whether the address provided corresponds to a contract created by the `Factory` contract.
66 |
67 |
68 | ## FundFactory.sol
69 |
70 | #### Description
71 |
72 | This contract manages and executes the orderly creation of a new Melon fund, linking all aspects of components, settings, routings and permissions.
73 |
74 |
75 | #### Inherits from
76 |
77 | Factory, AmguConsumer (link)
78 |
79 |
80 | #### On Construction
81 |
82 | The contract constructor requires the following address parameters and sets the corresponding address state variables:
83 |
84 | `address _accountingFactory` - The address of the Version's `AccountingFactory` contract.
85 | `address _feeManagerFactory` - The address of the Version's `FeeManagerFactory` contract.
86 | `address _participationFactory` - The address of the Version's `ParticipationFactory` contract.
87 | `address _sharesFactory` - The address of the Version's `SharesFactory` contract.
88 | `address _tradingFactory` - The address of the Version's `TradingFactory` contract.
89 | `address _vaultFactory` - The address of the Version's `VaultFactory` contract.
90 | `address _policyManagerFactory` - The address of the Version's `PolicyManagerFactory` contract.
91 | `address _registry` - The address of the Version's `Registry` contract.
92 | `address _version` - The address of the `Version` contract.
93 |
94 |
95 | #### Structs
96 |
97 | `Settings`
98 |
99 | Member variables:
100 |
101 | `string name` - The name of the Melon fund.
102 | `address[] exchanges` - An array of exchange contract addresses registered for the Melon fund.
103 | `address[] adapters` - An array of exchange adapter contract addresses registered for the Melon fund.
104 | `address denominationAsset` - The address of the asset token in which the Melon fund is denominated.
105 | `address nativeAsset` - The address of the asset token designated as the Melon fund's native asset, i.e. the Melon fund's native network token.
106 | `address[] defaultAssets` - An array of addresses designating the Melon fund's accepted asset tokens for subscription.
107 | `bool[] takesCustody` - An array of booleans mirroring an exchange contract's `takesCustody` state variable.
108 | `address priceSource` - The address of the Melon fund's price source.
109 | `address[] fees` - An array of addresses of the Melon fund's registered `fee` contracts.
110 | `uint[] feeRates` - An array of integers representing the fee rates registered for the Melon fund.
111 | `uint[] feePeriods` - An array of integer representing the the duration of a fee performance measurement period in seconds.
112 |
113 |
114 | #### Enums
115 |
116 | None.
117 |
118 |
119 |
120 | #### Modifiers
121 |
122 | `modifier componentNotSet(address _component)`
123 |
124 | This modifier enables a function to enforce the single execution of the implementing function and is evaluated prior to executing the implementing function's functionality.
125 |
126 |
127 | `modifier componentSet(address _component)`
128 |
129 | This modifier requires that the provided `_component` is set, i.e. exists.
130 | The condition is evaluated prior to executing the implementing function's functionality.
131 |
132 |
133 | #### Events
134 |
135 | NewFund()
136 |
137 | `address indexed manager` - The address of the Melon fund's manager.
138 | `address indexed hub` - The address of the Melon fund's `hub`.
139 | `address[12] routes` - An array of 12 address representing relevant Melon fund component addresses.
140 |
141 | This event is emitted when the FundFactory creates a new fund. The event logs the parameters listed above.
142 |
143 |
144 | #### Public State Variables
145 |
146 | `VersionInterface public version`
147 |
148 | This public state variable represents the Version contract.
149 |
150 |
151 | `address public registry`
152 |
153 | This public state variable represents the Version's Registry contract.
154 |
155 |
156 | `AccountingFactory public accountingFactory`
157 |
158 | This public state variable represents the Version's AccountingFactory contract.
159 |
160 |
161 | `FeeManagerFactory public feeManagerFactory`
162 |
163 | This public state variable represents the Version's FeeManagerFactory contract.
164 |
165 |
166 | `ParticipationFactory public participationFactory`
167 |
168 | This public state variable represents the Version's ParticipationFactory contract.
169 |
170 |
171 | `PolicyManagerFactory public policyManagerFactory`
172 |
173 | This public state variable represents the Version's PolicyManagerFactory contract.
174 |
175 |
176 | `SharesFactory public sharesFactory`
177 |
178 | This public state variable represents the Version's SharesFactory contract.
179 |
180 |
181 | `TradingFactory public tradingFactory`
182 |
183 | This public state variable represents the Version's TradingFactory contract.
184 |
185 |
186 | `VaultFactory public vaultFactory`
187 |
188 | This public state variable represents the Version's VaultFactory contract.
189 |
190 |
191 | `address[] public funds`
192 |
193 | This public state variable address array represents all fund contract addresses created by the FundFactory.
194 |
195 |
196 | `mapping (address => address) public managersToHubs`
197 |
198 | This public state variable mapping maps an address to an address, creating a relationship of manager to `hub`.
199 |
200 |
201 | `mapping (address => Hub.Routes) public managersToRoutes`
202 |
203 | This public state variable mapping maps an address to a `Routes` struct, creating a relationship of manager to `Routes`.
204 |
205 |
206 | `mapping (address => Settings) public managersToSettings`
207 |
208 | This public state variable mapping maps an address to `Settings` struct, creating a relationship of manager to `Settings`. This mapping is only used internally.
209 |
210 |
211 | #### Public Functions
212 |
213 | `function beginSetup(
214 | string _name,
215 | address[] _fees,
216 | uint[] _feeRates,
217 | uint[] _feePeriods,
218 | address[] _exchanges,
219 | address[] _adapters,
220 | address _denominationAsset,
221 | address _nativeAsset,
222 | address[] _defaultAssets,
223 | bool[] _takesCustody
224 | ) public componentNotSet(managersToHubs[msg.sender])`
225 |
226 | This public function takes the following parameters and initiates the set up process of a Melon fund. The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function requires that the Version is not shut down. The function then creates a new `Hub` owned by `msg.sender` with the `name` provided. The `Hub` is then added to the `managersToHubs` mapping, mapped to the `msg.sender` (manager). A `Settings` struct is constructed from the requisite parameter values and is added to the `managersToSettings` mapping, mapped to the `msg.sender` (manager). Finally, the function the proceeds to populate the `managersToRoutes` mapping by mapping the `msg.sender` (manager) address to the following individual `Routes` elements: `priceSource`, `registry`, `version`, `engine` and `mlnToken`.
227 |
228 |
229 | `function createAccounting()
230 | external
231 | componentSet(managersToHubs[msg.sender])
232 | componentNotSet(managersToRoutes[msg.sender].accounting)
233 | amguPayable(false)
234 | payable`
235 |
236 | This external function creates the Accounting spoke of a Melon fund and adds the resulting contract address to the `managersToRoutes` mapping, mapped to the `msg.sender` (manager). The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function is `payable` and also implements the `amguPayable` modifier, requiring amgu payment. Here, the `deductIncentive` parameter is set to `false`.
237 |
238 |
239 | `function createFeeManager()
240 | external
241 | componentSet(managersToHubs[msg.sender])
242 | componentNotSet(managersToRoutes[msg.sender].feeManager)
243 | amguPayable(false)
244 | payable`
245 |
246 | This external function creates the FeeManager spoke of a Melon fund and adds the resulting contract address to the `managersToRoutes` mapping, mapped to the `msg.sender` (manager). The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function is `payable` and also implements the `amguPayable` modifier, requiring amgu payment. Here, the `deductIncentive` parameter is set to `false`.
247 |
248 |
249 | `function createParticipation()
250 | external
251 | componentSet(managersToHubs[msg.sender])
252 | componentNotSet(managersToRoutes[msg.sender].participation)
253 | amguPayable(false)
254 | payable`
255 |
256 | This external function creates the Participation spoke of a Melon fund and adds the resulting contract address to the `managersToRoutes` mapping, mapped to the `msg.sender` (manager). The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function is `payable` and also implements the `amguPayable` modifier, requiring amgu payment. Here, the `deductIncentive` parameter is set to `false`.
257 |
258 |
259 | `function createPolicyManager()
260 | external
261 | componentSet(managersToHubs[msg.sender])
262 | componentNotSet(managersToRoutes[msg.sender].policyManager)
263 | amguPayable(false)
264 | payable`
265 |
266 | This external function creates the PolicyManager spoke of a Melon fund and adds the resulting contract address to the `managersToRoutes` mapping, mapped to the `msg.sender` (manager). The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function is `payable` and also implements the `amguPayable` modifier, requiring amgu payment. Here, the `deductIncentive` parameter is set to `false`.
267 |
268 |
269 | `function createShares()
270 | external
271 | componentSet(managersToHubs[msg.sender])
272 | componentNotSet(managersToRoutes[msg.sender].shares)
273 | amguPayable(false)
274 | payable`
275 |
276 | This external function creates the Shares spoke of a Melon fund and adds the resulting contract address to the `managersToRoutes` mapping, mapped to the `msg.sender` (manager). The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function is `payable` and also implements the `amguPayable` modifier, requiring amgu payment. Here, the `deductIncentive` parameter is set to `false`.
277 |
278 |
279 | `function createTrading()
280 | external
281 | componentSet(managersToHubs[msg.sender])
282 | componentNotSet(managersToRoutes[msg.sender].trading)
283 | amguPayable(false)
284 | payable`
285 |
286 | This external function creates the Trading spoke of a Melon fund and adds the resulting contract address to the `managersToRoutes` mapping, mapped to the `msg.sender` (manager). The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function is `payable` and also implements the `amguPayable` modifier, requiring amgu payment. Here, the `deductIncentive` parameter is set to `false`.
287 |
288 |
289 | `function createVault()
290 | external
291 | componentSet(managersToHubs[msg.sender])
292 | componentNotSet(managersToRoutes[msg.sender].vault)
293 | amguPayable(false)
294 | payable`
295 |
296 | This external function creates the Vault spoke of a Melon fund and adds the resulting contract address to the `managersToRoutes` mapping, mapped to the `msg.sender` (manager). The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function is `payable` and also implements the `amguPayable` modifier, requiring amgu payment. Here, the `deductIncentive` parameter is set to `false`.
297 |
298 |
299 | `function completeSetup()
300 | external
301 | amguPayable(false)
302 | payable`
303 |
304 | This external function completes the set up of a Melon fund. The function ensure the `childExists` mapping does not contain the `hub` address, then adds the `hub` address. The function then sets all of the `hub`'s spokes, routing, permissions and then adds the `hub` address to the `funds` state variable address array. The new Melon fund is then registered with the Version Registry. The function finally emits the `NewFund()` event, logging all parameter values as specified above. The function implements the `componentNotSet()` modifier ensuring its one-time execution in the Melon fund setup process. The function is `payable` and also implements the `amguPayable` modifier, requiring amgu payment. Here, the `deductIncentive` parameter is set to `false`.
305 |
306 |
307 | `function getFundById(uint withId) external view returns (address)`
308 |
309 | This external view function returns the address of the Melon fund given the `withId` value provided, which is the index of of the `funds` address array state variable.
310 |
311 |
312 | `function getLastFundId() external view returns (uint)`
313 |
314 | This external view function returns the index position of the most recently added Melon fund to the `funds` array state variable.
315 |
316 |
317 | `function engine() public view returns (address)`
318 |
319 | This public view function returns the address of the Melon Engine contract.
320 |
321 |
322 | `function mlnToken() public view returns (address)`
323 |
324 | This public view function returns the address of the MLN token contract.
325 |
326 |
327 | `function priceSource() public view returns (address)`
328 |
329 | This public view function returns the address of the PriceSource contract.
330 |
331 |
332 | `function version() public view returns (address)`
333 |
334 | This public view function returns the address of the Version contract.
335 |
336 |
337 | `function registry() public view returns (address)`
338 |
339 | This public view function returns the address of the Registry contract.
340 |
341 |
342 | ## FundRanking.sol
343 |
344 | #### Description
345 |
346 | The contract defines a function which returns specified information on each Melon fund created under a specific Version.
347 |
348 |
349 | #### Inherits from
350 |
351 | None.
352 |
353 |
354 |
355 | #### On Construction
356 |
357 | None.
358 |
359 |
360 |
361 | #### Structs
362 |
363 | None.
364 |
365 |
366 |
367 | #### Enums
368 |
369 | None.
370 |
371 |
372 |
373 | #### Modifiers
374 |
375 | None.
376 |
377 |
378 |
379 | #### Events
380 |
381 | None.
382 |
383 |
384 |
385 | #### Public State Variables
386 |
387 | None.
388 |
389 |
390 |
391 | #### Public Functions
392 |
393 | `function getFundDetails(
394 | address _factory)
395 | external
396 | view
397 | returns(
398 | address[],
399 | uint[],
400 | uint[],
401 | string[],
402 | address[])`
403 |
404 | This public view function gathers and returns the following Melon platform details for a specific Version, given the FundFactory address provided:
405 |
406 | `address[]` - An exhaustive array of Hub (i.e. Melon fund) addresses.
407 | `uint[]` - An exhaustive array of each Melon fund's current share price.
408 | `uint[]` - An exhaustive array of each Melon fund's creation time.
409 | `string[]` - An exhaustive array of each Melon funds' name.
410 | `address[]` - An exhaustive array of each Melon fund's denomination asset token address.
411 |
412 |
--------------------------------------------------------------------------------
/chapters/governance.md:
--------------------------------------------------------------------------------
1 | # Governance
2 |
3 | Read the full post here: https://medium.com/melonport-blog/introduction-to-the-melon-governance-system-f6ff73c70eb0
4 |
5 | ## Introduction to the Melon Governance System
6 | Melon ([méllōn], μέλλωv; Greek for “future”) is an open-source protocol for on-chain asset management. It is a blockchain software system that seeks to enable participants to set up, manage and invest in technology regulated and operated funds in a way that reduces barriers to entry, whilst minimizing the requirements for trust [1]. The Melon protocol is a set of rules implementing the behavior of an investment fund as a system of smart contracts. These rules are also meant to protect the investor and fund manager from malevolent behavior of each other, even when both parties remain private.
7 |
8 | The Melon protocol has been developed by Melonport AG. In February 2019, Melonport AG is expected to deliver v1.0 of the Melon protocol to the community, before winding down the company. This post addresses the question of future developments, maintenance and decisions relating to the Melon protocol once Melonport AG steps down as sole developer and maintainer.
9 |
10 |
11 | ## Mission statement
12 |
13 | The Melon protocol enables a new class of investment funds, referred to as Technology Regulated and Operated Funds (TROF). A TROF constitutes a first-of-its-kind on-chain and decentralized investment vehicle, made possible through leveraging decentralized technologies. Melon enables participants to perform the operational, compliance and administrative parts of asset management at a fraction of the cost, with higher transparency, security, and minimal trust requirements.
14 |
15 | Beyond the software, Melon aims to provide an infrastructure for the asset management of the future, “μέλλωv” (Greek for “future”). The large variety of applications (eg. VC, pension funds, insurance, hedge funds, etc) in on-chain asset management need a solid infrastructure to build upon, and Melon can be seen as such; it is the backbone of the on-chain asset management, or asset management 3.0.
16 |
17 | Melon is pioneering the way for open-source on-chain finance and, as such, is not intended to be owned by a single entity. Rather, it should be seen as an open-source public good. Melon was built in a way that is permissionless, inclusive, reliable and transparent. Users are defined as both asset managers and investors interacting with funds operating on the Melon protocol. Users do not need permission to interact with Melon.
18 |
19 | The main goals of Melon can be summarized as:
20 |
21 | - Providing a robust infrastructure for on-chain asset management
22 | - Providing a reliable, secure and transparent tool for managing investment funds on-chain
23 | - Lowering barriers to entry to what is forecast to be an $84.9 trillion asset management industry by 2025 [2]
24 | - Nurturing innovation in the asset management industry
25 |
26 | ## Governance purposes
27 |
28 | “It’s about the processes that participants in governance use to make decisions. It’s also about how they coordinate around decisions and decision-making processes. It includes the establishment, maintenance, and revocation of the legitimacy of decisions, decision making processes, norms, and other mechanisms for coordination” , Vlad Zamfir. [3]
29 |
30 | As part of the open-source finance stack, Melon is not owned by Melonport AG. In February 2019, Melonport AG will deploy v1.0 of the Melon protocol. Upon deployment, Melonport AG will no longer remain sole maintainer/developer of Melon. Therefore, as part of releasing the project in the hands of the community, Melonport AG aims at proposing a governance structure and decision-making processes that will underpin the Melon ecosystem and shall drive future development, acceptance and adoption of the Melon protocol.
31 |
32 | To that point, it is pertinent to address the following:
33 |
34 | - What it the scope of the decision-making processes (what)
35 | - Principles, values and goals that shall underpin any future decision (why)
36 | - Decision-making processes and roles (how)
37 |
38 | ### What future matters require decision-making capabilities?
39 |
40 | This section aims to address the what.
41 |
42 | *(i) Protocol upgrades*
43 |
44 | Future improvements to the Melon protocol smart contracts including bug fixes, security patches, feature additions, and third-party integrations. This also includes adding new assets to the Melon Asset Universe, as well as authorizing new exchanges to interact with the Melon protocol.
45 |
46 | Generally, protocol upgrades refer to changes in the Melon smart contracts codebase.
47 |
48 | *(ii) Resource allocation*
49 |
50 | Inflation [4] is the only financial resource available to the Melon community and a critical source for future growth and network effects. The yearly inflation of MLN is intended to be used to fund future developments of the Melon protocol, as well as projects building in the Melon ecosystem.
51 |
52 | Decisions need to be made as to:
53 |
54 | The definition of priorities regarding changes or additions to the protocol
55 | Choosing adequate developers to conduct specific research or implementation
56 | Reviewing and assessing asset management projects applying for funding
57 |
58 | *(iii) Network parameters*
59 |
60 | The asset management gas price per amgu (asset management gas unit) needs to be set and adjusted according to network usage and market conditions. For more context on this, please refer to Melonomics 2.
61 |
62 | ### Which long term goals and principles should underpin Melon related decisions?
63 |
64 | This section aims at addressing the why.
65 |
66 | Melon is intended to be a robust, secure and censorship resistant asset management infrastructure.
67 |
68 | The system aims at being drastically more efficient than any other existing solution. Melon is competitive to existing asset management alternatives and needs to remain competitive in the future. Melon constitutes an opt-in alternative to the current asset management industry.
69 |
70 | Melon is inclusive and permissionless. It should be easily accessible without restriction, to anyone on earth, no matter where they are.
71 |
72 | Lowering barriers to entry. Melon should always strive to lower barriers to entry for asset managers. It also gives investors access to a deeper and more accessible talent pool.
73 |
74 | Putting users first. It should be clear that the goal is to provide a best-in-class tool to asset managers around the world. Melon aims to stay ahead of the curve and provide advanced and sophisticated infrastructure to all kinds of asset managers.
75 |
76 | Any decisions taken in the future should be in line with the following long term goals:
77 |
78 | - 1 Preserving the integrity of the network
79 |
80 | - 2 Maximizing user adoption
81 |
82 | - 3 Fostering innovation and increasing network attractiveness
83 |
84 | Ultimately, those three goals should have a long-term positive effect on the value of the MLN token.
85 |
86 | ## Melon Governance System 1.0
87 |
88 | This section aims at addressing the how and presenting our current thinking for the Melon Governance System.
89 |
90 | When defining this governance model, our unique goal has been to think about what is best for the Melon protocol’s longevity, integrity and success, whilst keeping in mind the experimental aspect of this type of organization.
91 |
92 | “Governance is hard, especially for decentralized protocols. Allowing a community to govern a protocol does not make it any easier”, Dean Eigenmann [9]
93 |
94 | The initial Melon governance system is very user-centric, and ensures the maintenance and development are driven by technically informed parties.
95 |
96 | ### 1. Melon Technical Council (MTC) and Melon Council (MC)
97 | We therefore propose a technical council (see also technocratic council [10]) composed of a diverse set of known and identified entities or persons solely responsible for the following:
98 |
99 | - Deployment of protocol upgrades (including code upgrades, feature additions and bug fixes)
100 |
101 | - Management of the set of ENS subdomains pointing to the Melon smart contracts
102 |
103 | - Allocation of resources to developers and application developers.
104 |
105 | - Adjusting network parameters such as the cost per amgu (or Melon gas price)
106 |
107 | The formation of a council aims at providing more efficiency in the decision-making system (in comparison to a token holder governance model), but also at aligning the decision-makers with the best interests of the Melon protocol and its surrounding ecosystem (through fiduciary duties towards users). It minimizes the number of decision makers and ensures those decision-makers are accordingly qualified.
108 |
109 | The Melon Council (MC) is comprised of the MTC (Melon Technical Council) members and of the MEB (Melon Exposed Businesses) representatives.
110 |
111 | #### Formation of the Melon Technical Council
112 |
113 | There were a number of considerations to make when deciding on the makeup of this body. We evaluated the possibility of having token holders elect the council, but concluded that this is still susceptible to the eventual plutocracy outlined above. Instead, we aim at promoting a skill-based, meritocratic system.
114 |
115 | The Melon Technical Council (MTC) will initially be appointed by the Melonport AG team, prior to the main net v1.0 deployment of Melon in February 2019. That means that Melonport AG will initially allocate an odd number of seats on the MTC, and ensure that those seats are occupied by diverse actors, with the right set of skills, expertise and incentives.
116 |
117 | Subsequent to that, the MTC will grow organically by holding a Melon Council two-thirds vote on incoming applications. Incoming applications shall be reviewed by the existing members and approval or rejection shall be communicated with the according rationale.
118 |
119 | The MTC is a subset of the Melon Council (MC). MTC members will be joined by MEB members (see MEB section below and MC statutes) to form the Melon Council. It is expected that the Melon Council will evolve in a consortium-like fashion of technically skilled and business exposed parties.
120 |
121 | #### Melon Technical Council inclusions/exclusions
122 |
123 | Applicants to the Technical Council shall meet the following criteria [11]:
124 |
125 | Provable technical skills and expertise with regards to Melon (its codebase, token economics, ecosystem) and/or existing meaningful contribution to the Melon codebase
126 | A declared absence of any conflict of interest with the Melon vision and ecosystem
127 | Willingness and ability to dedicate time and resources to the Technical Council activities
128 | High evidenced ethical standards, good reputation and compliance with the MC statutes
129 | Willingness to reveal their identity
130 | The decision-making processes shall be open and transparent to the community. The Melon Council will be responsible for providing context to their decisions to the community. The Melon Council may or may not decide to consult the token holders sentiments on a specific topic.
131 |
132 | Melon Council members can be excluded through a ⅔ majority vote of the MEB (see MEB section and MC statutes)
133 |
134 | #### Fiduciary duties
135 |
136 | The Melon Council will be bound by fiduciary duties, guiding principles and MC statutes. This means the MC members will be obligated to act in the best interest of the Melon protocol. Any member violating their fiduciary duties will expose themselves to the revocation of their seat.
137 |
138 | If a MC member has a conflict of interest on a specific question, they should inform the rest of the members immediately and abstain from voting on the matter in question.
139 |
140 | #### MTC Incentivization model
141 |
142 | The people with the right skills for the MTC are scarce so we need to provide the right incentives structure for the MTC members. We therefore propose to ring-fence x% of the MLN annual inflation pool to reward the MTC members. The MLN tokens received by MTC members will be vested.
143 |
144 | Initially this should just cover their costs, but by providing that reward as a percentage of the annual inflation (ie. a proportion of total market cap), we also introduce an incentive to grow the market cap of Melon through adding value to the network.
145 |
146 | This has a size self-balancing side effect: as the pools of incentives grows, the MTC can grow. If the pool of incentives decreases (ie. market cap decreases), it is likely that some members of the MTC will resign or be forced out as it will no longer be worth their time and effort. This will in turn grow the asset pool for the remaining members. At the same time, if the number of MTC members becomes too small and the pool of available assets grows, more members will be attracted in.
147 |
148 | Note here that only MTC (not MEB representatives) members are eligible for this pool of reward.
149 |
150 | #### Protocol upgrades
151 |
152 | When a protocol upgrade is needed (feature addition, bug fixes or security vulnerability), the MTC can either implement the upgrade itself or mandate an external developer or entity to conduct the implementation.
153 |
154 | Once the implementation is finished, the new code must be audited by an independent party. If the audit passes and the majority of the MTC agrees, the new contracts can be deployed.
155 |
156 | The MTC owns the key of the owner address of the Melon ENS subdomains. The sole power of the MTC lies in their ability to change the ENS subdomain pointers of the Melon smart contracts to the newly deployed contracts. Note here that only the MTC (and not the whole MC!) approval is needed to update the ENS subdomain pointers.
157 |
158 | The MTC does not have the power to force an upgrade on the user or to shut down a previous version. The responsibility to run secure and up-to-date code relies solely on the user.
159 |
160 | #### Resource allocation
161 |
162 | The Melon protocol aims at providing the right set of incentives to the people maintaining it and developing it. The inflation (whose curve has yet to be defined) will be used solely for this purpose.
163 |
164 | The MTC will receive compensation from the inflation pool to cover costs associated with their duties as MTC members (as per MTC incentivization model above).
165 | Based on the defined roadmap and scheduled improvements, the Melon Council will compensate developers and contributors to the Melon protocol. The MC can either post bounties for specific desired features with the associated reward, or accept proposed MIPs by external developers.
166 | Projects in the asset management 3.0 industry can also apply for funding from the inflation pool (see Melonomics 1). The MC will then conduct a thorough review on funding requests. Approval of a project requires a 50% majority + 1 vote. The MC should only accept funding requests for projects that are expected to add a net value to the Melon ecosystem as a whole.
167 | Network parameters
168 |
169 | The Melon Engine mechanisms were recently presented in Melonomics 2. The MC will be provided with clear guidelines by the Melonport AG team with regards to adjustment of the amgu price (or Melon gas price). It will also be provided with the right tooling and framework to help make informed decisions.
170 |
171 | It is hard to predict today how often this variable will need to be adjusted, but we see two main factors that will drive this change:
172 |
173 | Burn rate, directly linked to usage levels of the network; as usage of the network goes up, the Melon gas price should go down to maintain a balanced and healthy burn rate.
174 | Market conditions on the MLN/ETH and ETH/USD pair
175 | More details on this part will be provided in a future blog post.
176 |
177 | Rotating leads and responsibilities
178 |
179 | We believe a group of people are more efficient when each person is held responsible and accountable.
180 |
181 | The MC should elect a Chair and a Vice-Chair at the beginning of each year. The Chair and Vice-Chair will be responsible for the coordination of the MC, its meetings and preparing the agendas.
182 |
183 | For the sake of efficiency (and to deter free-rider behavior), we propose a rotating lead system where every year, members can take a leadership role on specific topics such as: audits, features, ecosystem projects, network parameters etc. These may rotate every 6 months if necessary.
184 |
185 | ### 2. Developers
186 |
187 | The establishment of a technical council should not be seen as limiting contributions to the development of Melon to the members of the technical council. Participation in development is not limited to the MTC and should always be open to the public.
188 |
189 | The Melon protocol is entirely open-source, released under the GPL-3.0 license and, as such, any developer is invited to work on feature additions, third-party integrations, bug fixes and submit pull requests. Pull requests will be reviewed by the MTC. However, if a specific pull request is not merged by the MTC, that is not to say it can not be adopted by users.
190 |
191 | Developers can apply for funding by submitting proposals to the MC, under the form of Melon Improvement Proposals (MIP).
192 |
193 | Developers can also decide to implement a specific feature or improvement for which the MC shows strong interest. In that case the developer will receive the funding corresponding to the task at hand.
194 |
195 | Last but not least, developers having already contributed to the codebase, and willing to increase their engagement with Melon should strongly consider applying for a seat at the Melon Technical Council. If you are interested and meet the MTC requirements, reach out to mtc@melonport.com.
196 |
197 | ### 3. Users
198 |
199 | To be clear, the proposed Melon governance model is a user-centric model. It ensures users have permissionless access to a secure asset management protocol, and are protected from malevolent actors in the network. At the same time, users have the option to benefit from continuous innovation and improvements on top of the protocol, safeguarded by the thorough checks and analysis of the Melon Council bound by fiduciary duties. Indeed, the Melon Council is responsible for taking decisions preserving the interest of the users of the network.
200 |
201 | The users always remain in full control, and is the sole decision maker with regards to the software they are running.
202 |
203 | Neither the MC nor the token holders can impact the smart contract code used by a fund manager. The fund manager must take a voluntary action in order to upgrade to new versions of the code, and the fund’s investors are free to instantly redeem their shares if they are not happy with the version of the code being used. The fund manager is never forced to use a new version of the code they may or may not feel comfortable with. Users take full responsibility to upgrade from code that may contain security vulnerabilities.
204 |
205 | As a result, the convergence of users towards a specific version of the Melon protocol shall give a strong indication to the MC of their alignment with the users’ sentiments and needs. Although the MTC owns and controls the ENS subdomains pointing to the latest contracts, the users are the ones truly deciding which version to base their business upon, which constitutes a strong signal to the community. This is further enabled by the unstoppable character of smart contracts (once deployed, the Melon contracts can not be taken back by the deployer).
206 |
207 | However, users will be highly encouraged to always use the latest versions of the Melon protocol, as security vulnerabilities can be discovered and will be fixed in protocol upgrades. Users are also encouraged to conduct their own analysis, audit and review of the contracts they intend to use. The ultimate choice and responsibility relies solely on the user.
208 |
209 | ### 4. Melon Exposed Businesses (MEB)
210 |
211 | In order to guarantee that the voice of the users are heard and considered, it was deemed sensible to encourage the formation of the Melon Exposed Businesses.
212 |
213 | The intent is to unify the voices of users whose businesses heavily rely on Melon and its future development. This includes fund managers with a minimum threshold of assets managed on Melon (to be defined), or applications and projects utilising the Melon protocol.
214 |
215 | We aim for the MTC and MEB to maintain a close relationship and preserve a healthy feedback loop. The MTC will be required to address the concerns raised by the MEB, and both entities should work together at defining the pressing needs of the users of the network.
216 |
217 | Another important function of the MEB is to balance power by checking the decisions made by the MTC, and informing users about potential suspicious activity. The MEB will be able to elect its delegates to represent their interest on the Melon Council (see MC statutes). It is also possible for the MEB to vote on the exclusion of a Melon Council member violating the MC statutes (through a two-third majority vote).
218 |
219 | In the future, as more businesses build on Melon, it is expected that the MEB will grow in size. The Multichain Asset Managers Association (MAMA) as a trade body may be able to facilitate the organization of such a body.
220 |
221 | ***
222 |
223 | Rather than a static model, governance is a dynamic and complex process. The above model is a reflection of our current thinking, and it is what we would like to start with for the first few years, but it is expected to change and evolve over time. The Melon Council should also stay aware of the future developments in decentralized governance, as they might decide at some point in the future to migrate towards a new model.
224 |
--------------------------------------------------------------------------------
/chapters/melon_engine.md:
--------------------------------------------------------------------------------
1 | # Melon Engine: buy-and-burn model
2 |
3 | For context, please read Melonomics 2: https://medium.com/melonport-blog/melonomics-part-2-the-melon-engine-48bcb0dae65.
4 |
5 | The Melon Engine is a contract that collects fees paid in ETH for asset management gas units by the users, buys MLN at a premium to market with the collected ETH and burns the commensurate quantity of MLN. The Melon Engine mechanisms enable the alignment of the token value with the usage of the network, while avoiding the pitfalls of high-velocity token models.
6 |
7 | ## Perspective of a user interacting with the Melon protocol
8 |
9 | When a user interacts with an amgu (asset management gas unit) payable function on the Melon protocol, it pays asset management gas in ETH to the Melon network. We are still in the process of defining the functions that are amgu payable. As it stands, the following functions are amgu payable: `setupFund`, `requestInvestment`, `executeRequest` and `claimFees`.
10 |
11 | A modifier `amguPayable` is added to certain functions within the Melon protocol. That modifier will apply the logic which grants the user the ability to pay asset management gas.
12 |
13 | The total asset management gas paid is equal to: Number of amgu consumed * amgu price
14 |
15 | The initial amgu price will be set in MLN terms by Melonport AG before deployment in February. Thereafter, it will then be in the hands of the Melon Council to adjust the amgu price as necessary. According to our modeling, the Melon gas price (amgu price) should not need frequent adjustment. The 2 scenarios where we can expect an adjustment would be:
16 |
17 | - Overnight spike in network usage
18 | - Extreme volatility on MLN/USD
19 |
20 | The Melon gas price should always be kept at levels which make the Melon protocol competitive to other asset management alternatives. At the same time, the costs incurred must be sufficient to incentivize maintainers and developers compensated in MLN tokens.
21 |
22 |
23 | ## Melon Engine mechanics
24 |
25 | The ETH from the amgu fees paid by users is sent to the Melon Engine.
26 |
27 | The Melon Engine contract is a unidirectional liquidity contract that sells ETH and buys MLN at a premium over the market price (market price is retrieved through Kyber network).
28 |
29 | The Melon Engine maintains consecutive 1 month (60\*60\*24\*30 seconds) freeze periods. ETH received by the Melon Engine during a freeze period is held frozen in the Melon Engine until that freeze period ends. After 1 month, the function `thaw()` is publicly callable. Calling that function will render all frozen ETH liquid and available for external actors to buy ETH in exchange for MLN.
30 |
31 | As soon as the Melon Engine sells ETH and buys MLN, it burns the acquired MLN.
32 |
33 | The premium schedule provided by the Melon Engine is as follows:
34 | - Ether in the Melon Engine < 1 ETH, premium = 0%
35 | - 1≤ Ether in the Melon Engine < 5, premium = 5%
36 | - 5 ≤ Ether in the Melon Engine < 10, premium = 10%
37 | - Ether in the Melon Engine ≥ 10, premium = 15%
38 |
39 |
40 | ## Perspective of an actor interacting with the Melon Engine
41 |
42 | The Melon Engine premium is exclusive to Melon funds. Any Melon fund is eligible to call the `sellAndBurnMln` function on the Melon Engine, and may therefore benefit from the premium offered.
43 |
44 | **Use case**: As soon as ETH in the Melon Engine are liquid, a Melon fund can discretionarily sell MLN to the Melon Engine for ETH. This is done through the Melon Engine exchange adapter.
45 |
46 | Assume a Melon fund owns 10 MLN.
47 | - Through the Melon Engine exchange adapter, the Melon fund calls `sellAndBurnMln(10)`.
48 | - The function retrieves the amgu price from the Melon Engine (i.e. number of ETH the Melon Engine is willing to sell for 1 MLN, premium included).
49 | - The 10 MLN tokens the Melon fund sells are transferred to the Melon Engine contract.
50 | - The Melon Engine sends (10 * amgu price * (1+premium)) ETH to the Melon fund in exchange for the MLN tokens sold by the Melon fund.
51 | - The Melon Engine burns the MLN tokens collected in that transaction.
52 |
53 |
54 | ## AmguConsumer.sol
55 |
56 | #### Description
57 |
58 | This contract defines a function modifier which is used with functions where AMG (Asset Management Gas) is designed to be charged. Placing the modifier on a function affects the calculation of the functions gas usage and resulting AMGU charge. The resulting payment and excess refund to the sender is also handled by the functionality of the modifier. The contract also defines three helper functions to retrieve the contract addresses of the Melon Engine, MLN token and the price source.
59 |
60 |
61 | #### Inherits from
62 |
63 | DSMath (link)
64 |
65 |
66 |
67 | #### On Construction
68 |
69 | None.
70 |
71 |
72 |
73 | #### Structs
74 |
75 | None.
76 |
77 |
78 |
79 | #### Enums
80 |
81 | None.
82 |
83 |
84 |
85 | #### Modifiers
86 |
87 | `modifier amguPayable(bool deductIncentive)`
88 |
89 | This modifier determines the initial gas amount. The functionality in the function implementing this modifier is then executed. Thereafter, the AMGU (Asset Management Gas Unit) price and the MLN token market price is retrieved from the Melon Engine and the price feed, respectively. The modifier calculates the amount of ETH required for the payment of AMGU. Transactions with insufficient ETH amounts to pay the AMGU are reverted. ETH due as AMGU is paid to the Melon Engine and any excess ETH above the Ethereum gas costs and AMGU costs are refunded to the `msg.sender`.
90 |
91 |
92 | #### Events
93 |
94 | None.
95 |
96 |
97 |
98 | #### Public State Variables
99 |
100 | None.
101 |
102 |
103 |
104 | #### Public Functions
105 |
106 | `function engine() view returns (address)`
107 |
108 | This public view function returns the address of the Melon Engine contract.
109 |
110 |
111 | `function mlnToken() view returns (address)`
112 |
113 | This public view function returns the address of the MLN token contract.
114 |
115 |
116 | `function priceSource() view returns (address)`
117 |
118 | This public view function returns the address of the price feed contract.
119 |
120 |
121 | `function registry() view returns (address)`
122 |
123 | This public view function returns the address of the registry contract.
124 |
125 |
126 | ## Engine.sol
127 |
128 | #### Description
129 |
130 | This contract is a Melon fund exclusive, unidirectional exchange for Melon funds to exchange MLN tokens for ETH at a premium to market prices. The Melon Engine then reduces the total supply of the MLN token by burning all received MLN tokens.
131 |
132 |
133 | #### Inherits from
134 |
135 | DSMath, DSAuth (link)
136 |
137 |
138 |
139 | #### On Construction
140 |
141 | The constructor for this contract requires the parameters `_delay` and `_postDeployOwner`. The parameter `_delay` specifies the number of delay seconds, setting the `THAWING_DELAY` state variable to this value. The constructor sets the `lastThaw` state variable to the current `block.timestamp` value. Finally, the engine contract's owner is set to the `_postDeployOwner` address provided.
142 |
143 |
144 | #### Structs
145 |
146 | None.
147 |
148 |
149 |
150 | #### Enums
151 |
152 | None.
153 |
154 |
155 |
156 | #### Modifiers
157 |
158 | None.
159 |
160 |
161 |
162 | #### Events
163 |
164 | `event RegistryChange(address registry)`
165 |
166 | This event is triggered when the Version's Registry is set through the `setRegistry()` function, logging the `Registry` address.
167 |
168 |
169 | `event SetAmguPrice(uint amguPrice)`
170 |
171 | This event is triggered when the `setAmguPrice()` function is called, logging the modified `amguPrice`.
172 |
173 |
174 | `event Thaw(uint amount)`
175 |
176 | This event is triggered when the `thaw()` function is called, logging the thawed ETH `amount`.
177 |
178 |
179 | event AmguPaid(uint amount)
180 |
181 | This event is triggered when the `payAmguInEther()` function is called, logging the ETH `amount`.
182 |
183 |
184 | event Burn(uint amount)
185 |
186 | This event is triggered when the `sellAndBurnMln()` function is called, logging the burned MLN `amount`.
187 |
188 |
189 | #### Public State Variables
190 |
191 | `uint public frozenEther`
192 |
193 | This public state variable represents the quantity of ETH held by the Melon Engine which is currently frozen.
194 |
195 |
196 | `uint public liquidEther`
197 |
198 | This public state variable represents the quantity of ETH held by the Melon Engine which is not currently frozen.
199 |
200 |
201 | `uint public lastThaw`
202 |
203 | This public state variable represents the timestamp of the last, previous frozen ETH thaw.
204 |
205 |
206 |
207 | `uint public THAWING_DELAY`
208 |
209 | This public state variable represents the number of seconds required before frozen ETH is thawed.
210 |
211 |
212 | `BurnableToken public mlnToken`
213 |
214 | This public state variable represents MLN token contract which implements token burn functionality.
215 |
216 |
217 | `PriceSourceInterface public priceSource`
218 |
219 | This public state variable represents the Version's PriceSource contract.
220 |
221 |
222 | `Registry public registry`
223 |
224 | This public state variable represents the Version's Registry contract.
225 |
226 |
227 | `uint public MLN_DECIMALS = 18`
228 |
229 | This public state variable defines the decimal precision of the MLN token. It is set to the constant, 18.
230 |
231 |
232 | `uint public amguPrice`
233 |
234 | A public state variable specifying the current setting for the Asset Management Gas Unit (AMGU) price. This setting can be changed at the discretion of the Melon Technical Council (MTC).
235 |
236 | `uint public totalEtherConsumed`
237 |
238 | This public state variable keeps a running total of all ETH sent to the engine contract.
239 |
240 |
241 | `uint public totalAmguConsumed`
242 |
243 | This public state variable keeps a running total of all amgu consumed by the engine contract.
244 |
245 |
246 | `uint public totalMlnBurned`
247 |
248 | This public state variable keeps a running total of all MLN burned by the engine contract.
249 |
250 |
251 | #### Public Functions
252 |
253 | `function setRegistry(address _registry) external auth`
254 |
255 | This external function requires that the caller is the `owner` or the current contract. The function sets the `registry` state variable to the contract with the address specified by the parameter provided and further sets the `priceSource` and `mlnToken` state variables. Finally the function emits the `RegistryChange()` event, logging `registry`.
256 |
257 |
258 | `function setAmguPrice(uint _price) external auth`
259 |
260 | This external function requires that the caller is the `owner` or the current contract. The function sets the `amguPrice` state variable to the value specified by the parameter provided. Finally the function emits the `SetAmguPrice()` event, logging `amguPrice`.
261 |
262 |
263 | `function getAmguPrice() public view returns (uint)`
264 |
265 | This public view function returns the value of the `amguPrice` state variable.
266 |
267 |
268 | `function premiumPercent() public view returns (uint)`
269 |
270 | This public view function determines the market price premium to be offered when the Melon Engine buys MLN tokens. Please see the premium schedule above. The function returns an integer representing the premium percentage, e.g. a return value of "5" represents "5%".
271 |
272 |
273 | `function payAmguInEther() external payable`
274 |
275 | This external payable function is called while sending ETH. The function requires that the function caller must either be the fund managed by msg.sender or the fund factory used in the creation of the manager's fund. The function accepts the ETH amgu payment and increments the `frozenEther` state variable with the ETH value sent in the function call transaction. Finally, the function emits the `AmguPaid()` event, logging `amount` paid.
276 |
277 |
278 | `function thaw() external`
279 |
280 | This external function allocates frozen ETH (`frozenEther`) to liquid ETH (`liquidEther`) after the specified `THAWING_DELAY`. The function requires that sufficient time (minimally the `THAWING_DELAY`) has passed since the previous thaw. The function then requires that the quantity of frozen ETH is positive. The function then sets the `lastThaw` state variable to the current `block.timestamp`. The `liquidEther` state variable is incremented with the `frozenEther` state variable value, the `Thaw()` event is emitted, logging `frozenEther` value and finally, the `frozenEther` state variable is set to "0". Note: this function is independently and externally called. The `lastThaw` is only reset when this function is called, regardless of whether the previous `THAWING_DELAY` has expired.
281 |
282 |
283 | `function enginePrice() public view returns (uint)`
284 |
285 | This public view function returns the premium-adjusted ETH/MLN rate based on the quantity of ETH accumulated by the Melon Engine. The function first retrieves the MLN token price denominated in ETH. The calculated ETH-quantity scaled premium is then added to the market price and returned.
286 |
287 |
288 | `function ethPayoutForMlnAmount(uint mlnAmount) public view returns (uint)`
289 |
290 | This public view function returns the premium-adjusted quantity of ETH to be delivered to the Melon fund in return for selling the `mlnAmount` quantity of the MLN token.
291 |
292 |
293 | `function sellAndBurnMln(uint mlnAmount) external`
294 |
295 | This external function requires that the fund is the msg.sender, ensuring that only Melon funds may transact with the Melon Engine and benefit from the MLN token premium. The function then requires that approved MLN tokens be transferred from the Melon fund to the Melon Engine. The function calls `ethPayoutForMlnAmount()` to get the current quantity of ETH to send to the transacting Melon fund. This quantity is required to be positive and that a sufficient quantity of liquid ETH is held by the Melon Engine. The Melon Engine transfers the ETH to the transacting Melon fund and burns the received MLN tokens. Finally, the function emits the `Burn()` event, logging `mlnAmount` burned.
296 |
297 |
--------------------------------------------------------------------------------
/chapters/prices.md:
--------------------------------------------------------------------------------
1 | # Pricing
2 |
3 | ## General
4 |
5 | The Melon funds receive current pricing data from the Kyber Network, which in turn aggregates Kyber Reserve Managers providing markets for individual asset tokens. Asset prices are derived from the best price offered among participating reserve managers.
6 |
7 | The PriceSource interface definition is provided below. KyberPriceFeed.sol implements the PriceSource.i.sol interface.
8 |
9 |
10 | ## PriceSource.i.sol
11 |
12 | #### Description
13 |
14 | The PriceSource.i.sol is an interface definition intended to generalize the implementation of any concrete price source provider.
15 |
16 | #### Interface Functions
17 |
18 | `function getPriceInfo(address _asset) view returns (uint price, uint decimals)`
19 |
20 | This public view function returns the asset token price and the asset token decimal precision given the `_asset` address parameter provided.
21 |
22 |
23 | `function getInvertedPriceInfo(address ofAsset) view returns (uint price, uint decimals)`
24 |
25 | This public view function returns the asset token price provided by the `ofAsset` address parameter in terms of the `ofAsset` asset and decimal precision of the asset token address provided.
26 |
27 |
28 | `function getQuoteAsset() public view returns (address)`
29 |
30 | This public view function returns the address of asset token contract which was configured to be the base- or quote asset of the fund. The quote asset is the asset in which the fund's value is denominated.
31 |
32 |
33 | `function hasValidPrice(address) public view returns (bool)`
34 |
35 | This public view function returns a boolean indicating whether the asset represented by the address parameter provided is valid. A return value of `true` indicates that the asset has a valid price. A return value of `false` indicates that the asset does not have a valid price.
36 |
37 |
38 | `function hasValidPrices(address[]) public view returns (bool)`
39 |
40 | This public view function returns a boolean indicating whether all of the assets represented by the `address[]` array parameter provided are valid. A return value of `true` indicates that all asset tokens have valid prices. A return value of `false` indicates that one or more of the asset tokens do not have a valid price.
41 |
42 |
43 | `function getPrice(address _asset) public view returns (uint price, uint timestamp)`
44 |
45 | This public view function returns the price and price timestamp of the asset token given by the asset token address provided. The timestamp represents the time of the price quote.
46 |
47 |
48 | `function getPrices(address[] _assets) public view returns (uint[] prices, uint[] timestamps)`
49 |
50 | This public view function returns an array of prices and a corresponding array of price timestamps of the asset tokens given by the array of asset token addresses provided. The timestamps represent the times of the price quote.
51 |
52 |
53 | `function getReferencePriceInfo(address _base, address _quote) public view returns (uint referencePrice, uint decimal)`
54 |
55 | This public view function takes two address parameters: the base asset (the object of the pricing information) and the quote asset (the asset in which the price is denominated). The function returns the asset price provided by the `ofBase` address parameter in terms of the quote asset, and the specified asset token's `decimals` property.
56 |
57 |
58 | `function getOrderPriceInfo(address sellAsset, address buyAsset, uint sellQuantity, uint buyQuantity) public view returns (uint orderPrice)`
59 |
60 | This public view function returns a price given the provided sell asset and corresponding quantity, and the buy asset and corresponding quantity.
61 |
62 |
63 | `function existsPriceOnAssetPair(address sellAsset, address buyAsset) public view returns (bool isExistent)`
64 |
65 | This public view function returns a boolean indicating whether a recent price exists for the asset pair provided by the `sellAsset` and `buyAsset` address parameters.
66 |
67 |
68 | ## KyberPriceFeed.sol
69 |
70 | #### Description
71 |
72 | The KyberPriceFeed contract provides the interface from the version-specific Melon platform to the Kyber network for the purposes of receiving pricing data.
73 |
74 | #### Inherits from
75 |
76 | PriceSourceInterface, DSThing (link)
77 |
78 |
79 |
80 | #### On Construction
81 |
82 | The `KyberPriceFeed` contract requires the following parameters on construction:
83 |
84 | `address ofRegistrar` - The address of the Version's Registrar contract.
85 | `address ofKyberNetworkProxy` - The address of the Kyber network proxy contract.
86 | `uint ofMaxSpread` - The the maximum spread between bid- and ask prices for the price to be considered valid.
87 | `address ofQuoteAsset` - The address of the asset token contract which is the fund's base- or quote asset. All asset prices will be denominated or based in this asset token across all funds for the purposes of pricing.
88 |
89 | These parameters are used to set the the following public state variables on the contract:
90 |
91 | `KYBER_NETWORK_PROXY`
92 | `MAX_SPREAD`
93 | `QUOTE_ASSET`
94 | `REGISTRY`
95 |
96 |
97 | #### Structs
98 |
99 | None.
100 |
101 |
102 |
103 | #### Enums
104 |
105 | None.
106 |
107 |
108 |
109 | #### Modifiers
110 |
111 | None.
112 |
113 |
114 |
115 |
116 | #### Events
117 |
118 | None.
119 |
120 |
121 |
122 |
123 | #### Public State Variables
124 |
125 | `address public KYBER_NETWORK_PROXY`
126 |
127 | The address of the Kyber network proxy contract.
128 |
129 |
130 | `address public QUOTE_ASSET`
131 |
132 | The address of the asset token contract which is the fund's base- or quote asset.
133 |
134 |
135 | `Registry public REGISTRY`
136 |
137 | A public state variable which is the Registry contract of version under which the fund was deployed.
138 |
139 |
140 | `uint public MAX_SPREAD`
141 |
142 | A public state variable which represents the maximum spread between derived bid- and ask prices for specific asset pairs. `MAX_SPREAD` represents the maximum acceptable tolerance for a price to be valid. `MAX_SPREAD` is specified as a percentage and formatted in 10^18 terms. For example, 1.0% (0.01) would be represented 1x10^16 or 10000000000000000.
143 |
144 |
145 | `address public constant KYBER_ETH_TOKEN = 0x00eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`
146 |
147 | A constant public state variable which represents the token contract address of the ETH asset token.
148 |
149 |
150 | `uint public constant KYBER_PRECISION = 18`
151 |
152 | A constant public state variable which represents the divisibility precision of asset tokens...
153 |
154 |
155 | `uint public constant VALIDITY_INTERVAL = 2 days`
156 |
157 | A constant public state variable which represents the maximum validity of price feed prices and is set to "2 days".
158 |
159 | `uint public lastUpdate`
160 |
161 | An integer representing the time of the last price feed update.
162 |
163 |
164 | `mapping (address => uint) public prices`
165 |
166 | A public mapping associating an asset token contract address to the most recent price.
167 |
168 |
169 | #### Public Functions
170 |
171 | `function update()`
172 |
173 | This public function ensures that is can only be called by the `REGISTRY` owner. The function updates the `prices` mapping and the `lastUpdate` state variable. A price of "0" indicates an invalid price.
174 |
175 |
176 | `function getQuoteAsset() view returns (address)`
177 |
178 | This public view function returns the address of asset token contract which was configured to be the base- or quote asset of the fund. The quote asset is the asset in which the fund's value is denominated.
179 |
180 |
181 | `function getPrice(address _asset) view returns (uint price, uint timestamp)`
182 |
183 | This public view function returns the price and price timestamp of the asset token given by the asset token address provided. The price integer returned is formatted as the product of the exchange price and ten to the power of the asset's specified decimals property. The timestamp represents the time of the price quote.
184 |
185 |
186 | `function getPrices(address[] _assets) view returns (uint[], uint[])`
187 |
188 | This public view function returns an array of prices and a corresponding array of price timestamps of the asset tokens given by the array of asset token addresses provided. The price integers returned are formatted as the product of the exchange price and ten to the power of the asset's specified decimals property. The timestamps represent the times of the price quote.
189 |
190 |
191 | `function hasValidPrice(address _asset) view returns (bool)`
192 |
193 | This public view function returns a boolean indicating whether the asset represented by the `_asset` parameter provided is recent. The function first requires that the asset is registered in the registry. Passing the address of the quote asset will return `true`. If the price provided by the Kyber reserve manager is not 0, the price is assumed to be recent and will return `true`.
194 |
195 |
196 | `function hasValidPrices(address[] _assets) view returns (bool)`
197 | This public view function returns a boolean indicating whether the assets represented by the `_assets` address array parameter provided are all recent. The function requires that all assets passed in address array `_assets` parameter are registered in the registry. If any single asset in the array of asset addresses is not recent, the function will return `false`.
198 |
199 |
200 | `function getPriceInfo(address ofAsset) view returns (bool isRecent, uint price, uint assetDecimals)`
201 |
202 | This public view function calls the `getReferencePriceInfo()` function and returns a boolean indicating the validity of the price, the asset price provided by the `ofAsset` address parameter in terms of the quote asset, and the specified asset token's `decimals` property.
203 |
204 |
205 | `function getRawReferencePriceInfo(address _baseAsset, address _quoteAsset) view
206 | returns (bool isValid, uint referencePrice, uint decimals)`
207 |
208 | This public view function takes the `_baseAsset` and `_quoteAsset` token contract addresses and returns a boolean indicating price validity, the reference price and the asset token's decimal precision.
209 |
210 |
211 | `function getInvertedPriceInfo(address ofAsset) view returns (bool isRecent, uint invertedPrice, uint assetDecimals)`
212 |
213 | This public view function calls the `getReferencePriceInfo()` function and returns a boolean indicating the validity of the price, the asset price provided by the `ofAsset` address parameter in terms of the `ofAsset` asset, and the specified asset token's `decimals` property.
214 |
215 |
216 | `function getReferencePriceInfo(address _baseAsset, address _quoteAsset) view returns (uint referencePrice, uint decimals)`
217 |
218 | This public view function takes two address parameters: the base asset (the object of the pricing information) and the quote asset (the asset in which the price is denominated). [CHECK: function will we re-worked...]
219 |
220 |
221 | `function getOrderPriceInfo(address sellAsset, address buyAsset, uint sellQuantity, uint buyQuantity) view returns (uint orderPrice)`
222 |
223 | This public view function returns a price given the provided sell asset and corresponding quantity, and the buy asset and corresponding quantity.
224 |
225 |
226 | `function existsPriceOnAssetPair(address sellAsset, address buyAsset) view returns (bool isExistent)`
227 |
228 | This public view function returns a boolean indicating whether a recent price exists for the asset pair provided by the `sellAsset` and `buyAsset` address parameters.
229 |
230 |
231 | `function getKyberMaskAsset(address _asset) returns (address)`
232 |
233 | This public function returns the address of the Kyber Network representation contract adddress of the asset token contract address provided. If the address provided is ETH, the native token, the function returns `KYBER_ETH_TOKEN`; otherwise `_asset` is returned.
234 |
235 |
236 | `function getKyberPrice(address _baseAsset, address _quoteAsset) public view
237 | returns (bool isValid, uint kyberPrice)`
238 |
239 | This public view function takes the `_baseAsset` and `_quoteAsset` token contract addresses and returns a boolean indicating price validity and the average expected current Kyber Network price.
240 |
241 |
242 | `function convertQuantity(uint fromAssetQuantity, address fromAsset, address toAsset)
243 | public view returns (uint)`
244 |
245 | This public view function calculates and returns the quantity of the `toAsset` token which has a current value equal to the `fromAssetQuantity` of the `fromAsset` token.
246 |
247 |
248 | `function getLastUpdate() public view returns (uint)`
249 |
250 | This public view function returns the blocktime timestamp of the last price update, `lastUpdate`.
251 |
252 |
--------------------------------------------------------------------------------
/chapters/registry.md:
--------------------------------------------------------------------------------
1 | # Registry
2 |
3 | ## General
4 |
5 | The Registry contract is a singleton contract for all Version contracts. Each specific Melon protocol Version deploys funds generated of that specific version.
6 |
7 |
8 | ## Registry.sol
9 |
10 | #### Description
11 |
12 | The Registry contract stores, manages and provides functionality to maintain all relevant data pertaining to individual asset tokens and individual exchanges eligible for investment and operation within the Melon Protocol. The contract provides functionality to define, add, update or remove asset tokens and exchanges.
13 |
14 |
15 | #### Inherits from
16 |
17 | DSAuth (link)
18 |
19 |
20 | #### On Construction
21 |
22 | None.
23 |
24 |
25 | #### Structs
26 |
27 | `Asset`
28 |
29 | Member variables:
30 |
31 | `bool exists` - A boolean to conveniently and clearly indicate existence in a mapping.
32 | `string name` - The human-readable name of the asset token.
33 | `string symbol` - The human-readable symbol of the asset token.
34 | `uint decimals` - The divisibility precision of the token.
35 | `string url` - The URL for extended information of the asset token.
36 | `uint reserveMin` - An integer representing the Kyber Network reserve minimum.
37 | `uint[] standards` - An array of integers representing EIP standards to which this asset token conforms.
38 | `bytes4[] sigs` - An array of asset token function signatures which have been whitelisted.
39 |
40 |
41 | This struct stores all relevant information pertaining to the asset token.
42 |
43 |
44 | `Exchange`
45 |
46 | Member variables:
47 |
48 | `bool exists` - A boolean to conveniently and clearly indicate existence in a mapping.
49 | `address adapter` - The address of the exchange's corresponding adapter contract registered.
50 | `bool takesCustody` - A boolean indicating the custodial nature of the exchange.
51 | `bytes4[] sigs` - An array of exchange function signatures which have been whitelisted.
52 |
53 | This struct stores all relevant information pertaining to the exchange.
54 |
55 |
56 | Version
57 |
58 | Member variables:
59 |
60 | `bool exists` - A boolean to conveniently and clearly indicate existence in a mapping.
61 | `bytes32 name` - A 32 byte value type to represent the name of the Version.
62 |
63 | This struct stores all relevant information pertaining to the Version.
64 |
65 |
66 | #### Enums
67 |
68 | None.
69 |
70 |
71 |
72 | #### Modifiers
73 |
74 | `modifier only_version()`
75 |
76 | A modifier which requires `msg.sender` be a Version contract.
77 |
78 |
79 |
80 | #### Events
81 |
82 | `AssetUpsert()`
83 |
84 | `address indexed asset` - The address of the asset token contract registered.
85 | `string name` - The human-readable name of the asset token.
86 | `string symbol` - The human-readable symbol of the asset token.
87 | `uint decimals` - The divisibility precision of the token.
88 | `string url` - The URL for extended information of the asset token.
89 | `uint reserveMin` - An integer representing the Kyber Network reserve minimum.
90 | `uint[] standards` - An array of integers representing EIP standards to which this asset token conforms.
91 | `bytes4[] sigs` - An array of asset token function signatures which have been whitelisted.
92 |
93 | This event is triggered when an asset is added or updated in `registeredAssets`. The parameters listed above are provided with the event.
94 |
95 |
96 | `event ExchangeUpsert()`
97 |
98 | `address indexed exchange` - The address of the exchange contract registered.
99 | `address indexed adapter` - The address of the exchange's corresponding adapter contract registered.
100 | `bool takesCustody` - A boolean indicating the custodial nature of the exchange.
101 | `bytes4[] sigs` - An array of exchange function signatures which have been whitelisted.
102 |
103 | This event is triggered when an exchange is added or updated in `registeredExchanges`. The parameters listed above are provided with the event.
104 |
105 |
106 | `event AssetRemoval()`
107 |
108 | `address indexed asset` - The address of the registered asset token contract to be removed.
109 |
110 | This event is triggered when an asset is removed from the `registeredAssets` array state variable. The parameter listed above are provided with the event.
111 |
112 |
113 | `event ExchangeRemoval()`
114 |
115 | `address indexed exchange` - The address of the registered exchange contract to be removed.
116 |
117 | This event is triggered when an exchange is removed from the `registeredExchanges` array state variable. The parameter listed above are provided with the event.
118 |
119 |
120 | `event VersionRegistration()`
121 |
122 | `address indexed version` - The address of the Version registered.
123 |
124 | This event is triggered when a Version is registered. The parameter listed above are provided with the event.
125 |
126 |
127 | `event PriceSourceChange()`
128 |
129 | `address indexed priceSource` - The address of the new price source.
130 |
131 | This event is triggered when a price source is changed. The parameter listed above are provided with the event.
132 |
133 |
134 | `event MlnTokenChange()`
135 |
136 | `address indexed mlnToken` - The address of the new MLN token contract.
137 |
138 | This event is triggered when the MLN token is migrated to a new contract. The parameter listed above are provided with the event.
139 |
140 |
141 | `event NativeAssetChange()`
142 |
143 | `address indexed nativeAsset` - The address of the new native asset token contract.
144 |
145 | This event is triggered when the native asset token is migrated to a new contract. The parameter listed above are provided with the event.
146 |
147 |
148 | `event EngineChange()`
149 |
150 | `address indexed engine` - The address of the new Melon Engine contract.
151 |
152 | This event is triggered when the Melon Engine is migrated to a new contract. The parameter listed above are provided with the event.
153 |
154 |
155 | #### Public State Variables
156 |
157 | `mapping (address => Asset) public assetInformation`
158 |
159 | This public state variable mapping maps an asset token contract `address` to an `Asset` strut containing the asset information described above.
160 |
161 |
162 | `address[] public registeredAssets`
163 |
164 | This public state variable is an array of addresses which stores each asset token contract `address` which is registered.
165 |
166 |
167 | `mapping (address => Exchange) public exchangeInformation`
168 |
169 | This public state variable mapping maps an exchange contract `address` to an `Exchange` strut containing the exchange information described above.
170 |
171 |
172 | `address[] public registeredExchangeAdapters`
173 |
174 | This public state variable is an array of addresses which stores each exchange adapter contract `address` which is registered.
175 |
176 |
177 | `mapping (address => Version) public versionInformation`
178 |
179 | This public state variable mapping maps a Version contract `address` to a `Version` strut containing the Version information described above.
180 |
181 |
182 | `address[] public registeredVersions`
183 |
184 | This public state variable is an array of addresses which stores each Version contract `address` which is registered.
185 |
186 |
187 | `mapping (address => bool) public isFeeRegistered`
188 |
189 | This public state variable mapping maps a Fee contract `address` to a boolean indicating that the Fee contract is registered.
190 |
191 |
192 | `mapping (address => address) public fundsToVersions`
193 |
194 | This public state variable mapping maps a Version contract `address` to a Melon fund address.
195 |
196 |
197 | `mapping (bytes32 => bool) public versionNameExists`
198 |
199 | This public state variable mapping maps the Version name to a boolean indicating the Version name existence.
200 |
201 |
202 | `mapping (bytes32 => address) public fundNameHashToOwner`
203 |
204 | This public state variable mapping maps the hash of the fund name to the fund owner. A `bytes32` type is used, as dynamic-length types cannot be used as keys in mappings and a hash of the fund name allows for names longer than 32 bytes.
205 |
206 |
207 | `uint public constant MAX_REGISTERED_ENTITIES = 20`
208 |
209 | This public constant state variable represents the maximum quantity of registered entities and is set to "20". This constant applies to Exchanges registered and Assets registered.
210 |
211 |
212 | `uint public constant MAX_FUND_NAME_BYTES = 66`
213 |
214 | This public constant state variable represents the maximum Melon fund name size in bytes. The maximum is set to 66 bytes.
215 |
216 |
217 | `address public priceSource`
218 |
219 | This public state variable is the address of the current, active price source contract.
220 |
221 |
222 | `address public mlnToken`
223 |
224 | This public state variable is the address of the Melon token contract.
225 |
226 |
227 | `address public nativeAsset`
228 |
229 | This public state variable is the address of the native asset token contract.
230 |
231 |
232 | `address public engine`
233 |
234 | This public state variable is the address of the Melon Engine contract.
235 |
236 |
237 | `address public ethfinexWrapperRegistry`
238 |
239 | This public state variable is the address of the Ethfinex Wrapper Registry contract.
240 |
241 |
242 | `uint public incentive = 10 finney`
243 |
244 | This public state variable defines the incentive amount in ETH. The variable is set to 10 finney.
245 |
246 |
247 | #### Public Functions
248 |
249 | `function registerAsset(
250 | address _asset,
251 | string _name,
252 | string _symbol,
253 | string _url,
254 | uint _reserveMin,
255 | uint[] _standards,
256 | bytes4[] _sigs
257 | ) external auth`
258 |
259 | This external function requires that the caller is the `owner` or the current contract. It then requires that the asset token's information not be previously registered. The asset token's address is then appended to the `registeredAssets` array state variable. The function then registers the following information for a specific asset token within the Registry contract as per the following parameters:
260 |
261 | `address _asset` - The address of the asset token contract to be registered.
262 | `string _name` - The human-readable name of the asset token.
263 | `string _symbol` - The human-readable symbol of the asset token.
264 | `string _url` - The URL for extended information of the asset token.
265 | `uint reserveMin` - An integer representing the Kyber Network reserve minimum.
266 | `uint[] _standards` - An array of integers representing EIP standards to which this asset token conforms.
267 | `bytes4[] _sigs` - An array of asset token function signatures which have been whitelisted.
268 |
269 | Finally, the function ensures that the asset token's information exists in the `assetInformation` mapping state variable.
270 |
271 |
272 | `function registerExchangeAdapter(
273 | address _exchange,
274 | address _adapter,
275 | bool _takesCustody,
276 | bytes4[] _sigs
277 | ) external auth`
278 |
279 | This external function requires that the caller is the `owner` or the current contract. It then requires that the exchange's information not be previously registered. The exchange's address is then appended to the `registeredExchanges` array state variable. The function then registers the following information for a specific exchange within the Registry contract as per the following parameters:
280 |
281 | `address _exchange` - The address of the exchange contract to be registered.
282 | `address _adapter` - The address of the exchange's corresponding adapter contract to be registered.
283 | `bool _takesCustody` - A boolean indicating the custodial nature of the exchange.
284 | `bytes4[] _sigs` - An array of exchange function signatures which have been whitelisted.
285 |
286 | Finally, the function ensures that the exchange's information exists in the `exchangeInformation` mapping state variable.
287 |
288 |
289 | `function updateAsset(
290 | address _asset,
291 | string _name,
292 | string _symbol,
293 | uint _decimals,
294 | string _url,
295 | uint _reserveMin,
296 | uint[] _standards,
297 | bytes4[] _sigs
298 | ) auth`
299 |
300 | This function requires that the caller is the `owner` or the current contract. It then requires that the asset token's information be previously registered. The function then updates the following information for a specific asset token within the Registry contract as per the following parameters:
301 |
302 | `address _asset` - The address of the asset token contract to be registered.
303 | `string _name` - The human-readable name of the asset token.
304 | `string _symbol` - The human-readable symbol of the asset token.
305 | `uint _decimals` - The divisibility precision of the token.
306 | `string _url` - The URL for extended information of the asset token.
307 | `uint reserveMin` - An integer representing the Kyber Network reserve minimum.
308 | `uint[] _standards` - An array of integers representing EIP standards to which this asset token conforms.
309 | `bytes4[] _sigs` - An array of asset token function signatures which have been whitelisted.
310 |
311 | Finally, the function emits the `AssetUpsert` event along with the parameters listed above.
312 |
313 |
314 | `function updateExchange(
315 | address _exchange,
316 | address _adapter,
317 | bool _takesCustody,
318 | bytes4[] _sigs
319 | ) auth`
320 |
321 | This function requires that the caller is the `owner` or the current contract. It then requires that the exchange's information be previously registered. The function then updates the following information for a specific exchange within the Registry contract as per the following parameters:
322 |
323 | `address _exchange` - The address of the exchange contract to be registered.
324 | `address _adapter` - The address of the exchange's corresponding adapter contract to be registered.
325 | `bool _takesCustody` - A boolean indicating the custodial nature of the exchange.
326 | `bytes4[] _sigs` - An array of exchange function signatures which have been whitelisted.
327 |
328 | Finally, the function emits the `ExchangeUpsert` event along with the parameters listed above.
329 |
330 |
331 |
332 | `function removeAsset(address _asset, uint _assetIndex) auth`
333 |
334 | This function requires that the caller is the `owner` or the current contract. The function requires the following parameters:
335 |
336 | `address _asset` - The address of the asset token contract to be removed.
337 | `uint _assetIndex` - The index of the asset provided in the registerAssets array state variable.
338 |
339 | The function then requires that the asset information exists and that the asset is registered. The function then deletes the asset's entries from the `assetInformation` mapping state variable and the `registeredAssets` array state variable, while also maintaining the `registeredAssets` array. The function ensures that the asset's information entry no longer exists and finally emits the `AssetRemoval()` event with the asset's token contract address.
340 |
341 |
342 | `function removeExchange(address _exchange, uint _exchangeIndex) auth`
343 |
344 | This function requires that the caller is the `owner` or the current contract. The function requires the following parameters:
345 |
346 | `address _exchange` - The address of the exchange contract to be removed.
347 | `uint _exchangeIndex` - The index of the exchange provided in the registerAssets array state variable.
348 |
349 | The function then requires that the exchange information exists and that the exchange is registered. The function then deletes the exchange's entries from the `exchangeInformation` mapping state variable and the `registeredExchanges` array state variable, while also maintaining the `registeredExchanges` array. The function ensures that the exchange's information entry no longer exists and finally emits the `ExchangeRemoval()` event with the exchange's contract address.
350 |
351 |
352 | `function getName(address _asset) view returns (string)`
353 |
354 | This public view function retrieves the asset token `name` for the registered asset address provided.
355 |
356 |
357 | `function getSymbol(address _asset) view returns (string)`
358 |
359 | This public view function retrieves the asset token `symbol` for the registered asset address provided.
360 |
361 |
362 | `function getDecimals(address _asset) view returns (uint)`
363 |
364 | This public view function retrieves the asset token `decimals` for the registered asset address provided. `decimals` specifies the divisibility precision of the token.
365 |
366 |
367 | `function assetIsRegistered(address _asset) view returns (bool)`
368 |
369 | This public view function indicates whether the address provided is that of a registered asset token. A return value of `true` indicates that the asset is registered. A return value of `false` indicates that the asset is not registered.
370 |
371 |
372 | `function getRegisteredAssets() view returns (address[])`
373 |
374 | This public view function returns an array of all registered asset token addresses.
375 |
376 |
377 | `function assetMethodIsAllowed(address _asset, bytes4 _sig) external view returns (bool)`
378 |
379 | This external view function returns a boolean indicating whether a specific asset token function is whitelisted given the provided asset token address and the function's signature hash. A return value of `true` indicates that the function is whitelisted. A return value of `false` indicates that the function is not whitelisted.
380 |
381 |
382 | `function exchangeIsRegistered(address _exchange) view returns (bool)`
383 |
384 | This public view function returns a boolean indicating whether a specific exchange is registered. A return value of `true` indicates that the exchange is registered. A return value of `false` indicates that the exchange is not registered.
385 |
386 |
387 | `function getRegisteredExchanges() view returns (address[])`
388 |
389 | This public view function returns an array of all registered exchange addresses.
390 |
391 |
392 | `function getExchangeInformation(address _exchange) view returns (address, bool)`
393 |
394 | This public view function returns the corresponding exchange adapter contract address and the exchange's boolean indicator `takesCustody` given the provided exchange contract address.
395 |
396 |
397 | `function getExchangeFunctionSignatures(address _exchange) view returns (bytes4[])`
398 |
399 | This public view function returns an array of whitelisted exchange function signatures corresponding to the provided exchange contract address.
400 |
401 |
402 | `function exchangeMethodIsAllowed(address _exchange, bytes4 _sig) returns (bool)`
403 |
404 | This public view function returns a boolean indicating whether a specific exchange function is whitelisted given the provided exchange address and the function's signature hash. A return value of `true` indicates that the function is whitelisted. A return value of `false` indicates that the function is not whitelisted.
405 |
406 |
407 | `function registerVersion(address _version, bytes32 _name) auth`
408 |
409 | This function requires that the caller is the `owner` or the current contract. The function sets the `versionInformation` mapping `exists` to `true`, `name` to `_name` and pushes the Version address on to the `registeredVersions` array. The `versionNameExists` mapping for this Version name is set to `true`. Finally, the `VersionRegistration()` event is emitted, logging the Version address. Versions cannot be removed from the registry.
410 |
411 |
412 | `function setPriceSource(address _priceSource) auth`
413 |
414 | This function requires that the caller is the `owner` or the current contract. The function sets the `priceSource` state variable to the `_priceSource` parameter value and emits the `PriceSourceChange()` event, logging `_priceSource`.
415 |
416 |
417 | `function setMlnToken(address _mlnToken) auth`
418 |
419 | This function requires that the caller is the `owner` or the current contract. The function sets the `mlnToken` state variable to the `_mlnToken` parameter value and emits the `MlnTokenChange()` event, logging `_mlnToken`.
420 |
421 |
422 | `function setNativeAsset(address _nativeAsset) auth`
423 |
424 | This function requires that the caller is the `owner` or the current contract. The function sets the `nativeAsset` state variable to the `_nativeAsset` parameter value and emits the `NativeAssetChange()` event, logging `_nativeAsset`.
425 |
426 |
427 | `function setEngine(address _engine) auth`
428 |
429 | This function requires that the caller is the `owner` or the current contract. The function sets the `engine` state variable to the `_engine` parameter value and emits the `EngineChange()` event, logging `_engine`.
430 |
431 |
432 | `function getReserveMin(address _asset) view returns (uint)`
433 |
434 | This public view function returns the `reserveMin` for the asset token contract address provided.
435 |
436 |
437 | `function adapterForExchange(address _exchange) view returns (address)`
438 |
439 | This public view function returns the address of the exchange adapter contract given the exchange contract address provided.
440 |
441 |
442 | `function getRegisteredVersions() view returns (address[])`
443 |
444 | This public view function returns an exhaustive array of addresses of all registered Version contracts.
445 |
446 |
447 | `function isFund(address _who) view returns (bool)`
448 |
449 | This public view function returns a boolean indicating whether the address provided is a Melon fund contract.
450 |
451 |
452 | `function isFundFactory(address _who) view returns (bool)`
453 |
454 | This public view function returns a boolean indicating whether the address provided is a FundFactory. The function check the existence of the `_who` address in the `versionInformation` mapping. Note that Version inherits FundFactory.
455 |
456 |
457 | `function registerFund(address _fund, address _owner, string _name) external only_version`
458 |
459 | This external function ensures that `msg.sender` is a Version, as only Versions can register funds. The function requires that the fund name is valid. The function then adds an entry to the `fundsToVersions` mapping, associating `_fund` to `msg.sender`, i.e. the Version address.
460 |
461 |
462 | `function isValidFundName(string _name) public view returns (bool)`
463 |
464 | This public function ensures that the fund name provided does not exceed `MAX_FUND_NAME_BYTES` nor contain restricted characters. Legal characters are "0-9", "a-z", "A-Z", " ", "-", ".", "\_" and "\*".
465 |
466 |
467 | `function canUseFundName(address _user, string _name) public view returns (bool)`
468 |
469 | This public function ensures that the fund name provided adheres to the rules set forth in `isValidFundName()`, and that the name is not already in use by a fund or is used by the provided `_user` address (to enable fund name reuse across Versions by the same `_user`).
470 |
471 |
472 | `function reserveFundName(address _owner, string _name) external only_version`
473 |
474 | This external function requires that that `msg.sender` is a Version and that `_name` passes all conditions of `canUseFundName()`, then adds `_name` to the `fundNameHashToOwner` mapping.
475 |
476 |
477 | `function registerFees(address[] _fees) external auth`
478 |
479 | This external function requires that the caller is the `owner` or the current contract. The Fee contract addresses provided are then added as entries to the `isFeeRegistered` mapping with the value of `true`.
480 |
481 |
482 | `function deregisterFees(address[] _fees) external auth`
483 |
484 | This external function requires that the caller is the `owner` or the current contract. The Fee contract addresses provided are then deleted from the `isFeeRegistered` mapping.
485 |
486 |
--------------------------------------------------------------------------------
/chapters/version.md:
--------------------------------------------------------------------------------
1 | # Version
2 |
3 | ## General
4 |
5 | The Version contract is a singleton contract for all funds deployed under a specific Melon protocol version. All Factory contracts are exclusive to the Version contract and cannot be changed once set.
6 |
7 |
8 |
9 | ## Version.sol
10 |
11 | #### Description
12 |
13 | The Version contract inherits from FundFactory and is the single, exclusive FundFactory contract for a specific Melon Protocol version. The Version contract is the contract creator for all funds of the specific Melon Protocol version.
14 |
15 | #### Inherits from
16 |
17 | FundFactory, DSAuth, VersionInterface (link)
18 |
19 |
20 |
21 | #### On Construction
22 |
23 | The following contract addresses are provided as parameters:
24 |
25 | `address _accountingFactory` - The address of the AccountingFactory contract.
26 | `address _feeManagerFactory` - The address of the FeeManagerFactory contract.
27 | `address _participationFactory` - The address of the ParticipationFactory contract.
28 | `address _sharesFactory` - The address of the SharesFactory contract.
29 | `address _tradingFactory` - The address of the TradingFactory contract.
30 | `address _vaultFactory` - The address of the VaultFactory contract.
31 | `address _policyManagerFactory` - The address of the PolicyManagerFactory contract.
32 | `address _registry` - The address of the Registry contract.
33 | `address _postDeployOwner` - The address of the contract owner.
34 |
35 | These address parameters set the corresponding state variables as defined in the inherited definition of `FundFactory`. The constructor then directly sets the `registry` state variable with the address of the registry contract and calls the `setOwner()` function passing the address of the current contract.
36 |
37 | The Version contract assumes the Governance contract is the deployer.
38 |
39 |
40 |
41 | #### Structs
42 |
43 | None.
44 |
45 |
46 |
47 | #### Enums
48 |
49 | None.
50 |
51 |
52 |
53 | #### Modifiers
54 |
55 | None.
56 |
57 |
58 |
59 |
60 | #### Events
61 |
62 | None.
63 |
64 |
65 |
66 | #### Public State Variables
67 |
68 | None.
69 |
70 |
71 |
72 | #### Public Functions
73 |
74 | `function shutDownFund(address _hub) external`
75 |
76 | This external function first requires that `msg.sender` is the manager for the specified `_hub`. The function then calls the target fund's `shutDownFund()` function.
77 |
78 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 |
--------------------------------------------------------------------------------