├── .gitignore
├── LICENSE
├── README-CN.md
├── README.md
├── app.html
├── assets
├── css
│ ├── theme-antd.less
│ └── theme.scss
└── img
│ └── common
│ └── close.png
├── build
├── module
│ ├── scss.txt
│ ├── ts.txt
│ └── vue.txt
└── page.js
├── components
├── business
│ └── TransactionDetail.vue
└── ui
│ ├── ZonCard.vue
│ └── ZonModal.vue
├── jest.config.js
├── jsconfig.json
├── layouts
└── default.vue
├── nuxt.config.js
├── package.json
├── pages
├── index.vue
├── newTransaction.vue
└── tokenContract.vue
├── plugins
├── antd-ui.js
├── app.ts
├── filter.ts
└── polyfill.ts
├── static
└── favicon.ico
├── store
├── contract.ts
└── index.ts
├── test
└── Logo.spec.js
├── timelock
├── abi
│ ├── cETH-abi.json
│ ├── cToken-abi.json
│ ├── comptroller-abi.json
│ ├── timelock-abi.json
│ └── unitroller-abi.json
├── constants.ts
├── contracts.ts
├── dataStorage.ts
├── error.ts
├── interface.ts
├── provider.ts
├── timelock.ts
└── wallet.ts
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Node template
3 | # Logs
4 | /logs
5 | *.log
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 |
10 | # Runtime data
11 | pids
12 | *.pid
13 | *.seed
14 | *.pid.lock
15 |
16 | # Directory for instrumented libs generated by jscoverage/JSCover
17 | lib-cov
18 |
19 | # Coverage directory used by tools like istanbul
20 | coverage
21 |
22 | # nyc test coverage
23 | .nyc_output
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # Bower dependency directory (https://bower.io/)
29 | bower_components
30 |
31 | # node-waf configuration
32 | .lock-wscript
33 |
34 | # Compiled binary addons (https://nodejs.org/api/addons.html)
35 | build/Release
36 |
37 | # Dependency directories
38 | node_modules/
39 | jspm_packages/
40 |
41 | # TypeScript v1 declaration files
42 | typings/
43 |
44 | # Optional npm cache directory
45 | .npm
46 |
47 | # Optional eslint cache
48 | .eslintcache
49 |
50 | # Optional REPL history
51 | .node_repl_history
52 |
53 | # Output of 'npm pack'
54 | *.tgz
55 |
56 | # Yarn Integrity file
57 | .yarn-integrity
58 |
59 | # dotenv environment variables file
60 | .env
61 |
62 | # parcel-bundler cache (https://parceljs.org/)
63 | .cache
64 |
65 | # next.js build output
66 | .next
67 |
68 | # nuxt.js build output
69 | .nuxt
70 |
71 | # Nuxt generate
72 | dist
73 |
74 | # vuepress build output
75 | .vuepress/dist
76 |
77 | # Serverless directories
78 | .serverless
79 |
80 | # IDE / Editor
81 | .idea
82 |
83 | # Service worker
84 | sw.*
85 |
86 | # macOS
87 | .DS_Store
88 |
89 | # Vim swap files
90 | *.swp
91 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 unizon-blockchain
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README-CN.md:
--------------------------------------------------------------------------------
1 | # Unizon timelock admin
2 |
3 | ## 目标
4 |
5 | Timelock已经成为高质量DeFi项目的标配,是治理体系不可或缺的一部分,通过Timelock接管/限制超级用户对系统参数的修改,一方面可以避免管理员作恶或者攻击者获取管理员权限后对系统造成严重破坏,另一方面也可以给用户以更大的权限,在用户不同意某些治理措施时有足够的时间提前行动,避免资产遭受损失。
6 |
7 | 目前业内普遍采纳了一个标准timelock合约,如同本项目所包含的,包括Compound、SushiSwap等项目均采用。但是,合约的使用与管理却没有一个比较简单、通行的方案,目前比较典型的有两类:一种是Sushiswap采用的简单查询方式,即把timelock合约所涉及的所有交易查询出来,按时间顺序展示,而不关心具体业务的操作逻辑。参见:https://sushi-timelock.txs.wtf/ 。另一种是与治理体系结合的比较完整的方式,如:Compound官网上展现的。
8 |
9 | 目前我们尚未看到一个完整的、面向timelock使用和管理的开源项目,能够帮助DeFi开发者快速使用和管理timelock。这种情况下,一个DeFi项目的管理者,想要有效使用timelock,会遇到两个主要的问题。一是要有相当的开发量,自己合约对应的所有函数都要自己来编写对应的timelock调用,开发工作量大,正确性难以有保障。二是如果参考sushiswap这种流水账式的组织方式,则无法从业务的角度去使用和管理timelock,比如:发起一个timelock交易修改平台的某个参数,并且在两天后timelock允许生效时对这个交易进行确认,这是一个典型的场景。但在Sushiswap这种原始的查询方式中,无法知道当前timelock中有哪些待执行交易、内容是什么,必须去浏览全部的,混杂在一起的各种交易(发起、确认、取消等),找到当初发起的交易再执行。
10 |
11 | 我们认为,一个有效的timelock管理框架,应当做到两点:一方面应当让项目通过配置的方式就可以将自己需要管理的方法交由timelock实现,无需大量的开发工作。另一方面数据组织形式应该更贴合业务逻辑,采用基于业务的组织方式,将QueueTransaction与ExecuteTransaction/CancelTransaction匹配、组织起来,简化管理员的工作。
12 |
13 | 这就是Unizon timelock Admin项目的来源。
14 |
15 | ## 功能简介
16 |
17 | 通用的timelock管理DAPP,通过修改配置文件即可实现timelock交易展示、queueTransaction、executeTransaction、cancelTransaction功能
18 |
19 | 修改/timelock/constants.ts文件更改配置文件(本配置以compound为例):
20 |
21 | ```javascript
22 | /**
23 | * timelock管理的合约地址,本配置以compound为例
24 | */
25 | export const contract_address : any = {
26 | 3: {
27 | 'unitroller': '0x52Ab60E7F463B73C6A90ee116dBB18ac61DC63FF',
28 | 'comptroller': '0x52Ab60E7F463B73C6A90ee116dBB18ac61DC63FF',
29 | 'cToken1': '',
30 | 'cToken2': '',
31 | 'cTokenn': ''
32 | },
33 | 1: {
34 | 'unitroller': '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B',
35 | 'comptroller': '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B',
36 | 'cToken1': '',
37 | 'cToken2': '',
38 | 'cTokenn': ''
39 | }
40 | }
41 |
42 | /**
43 | * timelock管理的合约所对应的abi文件, abi文件需拷贝至/timelock/abi目录
44 | */
45 |
46 | export const contract_abi_file : any = {
47 | 'unitroller': 'unitroller-abi.json',
48 | 'comptroller': 'comptroller-abi.json',
49 | 'cToken1': 'cToken-abi.json',
50 | 'cToken2': 'cToken-abi.json',
51 | 'cTokenn': 'cToken-abi.json'
52 | }
53 |
54 | /**
55 | * deplay Offset, unit: seconds
56 | */
57 | export const delay_offset = 300;
58 |
59 | /**
60 | * timelock合约地址, 分别为mainnet和ropsten,其中主网为compound timelock 合约地址
61 | */
62 | export const timelock_address : any = {
63 | 1: '0x6d903f6003cca6255D85CcA4D3B5E5146dC33925',
64 | 3: '0x4168FE8179C5e99074068244413909F40c4301B2'
65 | }
66 |
67 | /**
68 | * timelock管理的合约需要执行queueTransaction的函数列表
69 | */
70 |
71 | export const queue_functions : any = {
72 | 'unitroller': ['_acceptAdmin', '_setPendingAdmin', '_setPendingImplementation'],
73 | 'comptroller': ['_become', '_setBorrowPaused', '_setMiningBuff', '_setCompRate', '_setMintPaused', '_supportMarket', '_dropCompMarket', '_setPriceOracle', '_setCollateralFactor'],
74 | 'cToken1': ['_acceptAdmin', '_setReserveFactor'],
75 | 'cToken2': ['_acceptAdmin', '_setReserveFactor'],
76 | 'cTokenn': ['_acceptAdmin', '_setReserveFactor']
77 | }
78 |
79 | ```
80 | ## 运行及部署
81 |
82 | ### 运行:
83 |
84 | 在项目根目录执行
85 |
86 | ```shell
87 | yarn
88 | yarn dev
89 | ```
90 |
91 | ### 部署:
92 |
93 | 在项目根目录执行
94 |
95 | ```shell
96 | yarn build
97 | ```
98 | 通过nginx/apache部署./dist目录即可
99 |
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Unizon timelock admin
2 | Through the Timelock admin dapp interface, editing these settings below can allow for timelocked transactions via the queueTransaction, executeTransaction, and cancelTransaction functions.
3 |
4 | Please edit the /timelock/constants.ts file for the contract you wish to support - the original settings are designed for compound as an example
5 |
6 |
7 | ```javascript
8 | /**
9 | * Timelock admin smart contract address
10 | */
11 | export const contract_address : any = {
12 | 3: {
13 | 'unitroller': '0x52Ab60E7F463B73C6A90ee116dBB18ac61DC63FF',
14 | 'comptroller': '0x52Ab60E7F463B73C6A90ee116dBB18ac61DC63FF',
15 | 'cToken1': '',
16 | 'cToken2': '',
17 | 'cTokenn': ''
18 | },
19 | 1: {
20 | 'unitroller': '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B',
21 | 'comptroller': '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B',
22 | 'cToken1': '',
23 | 'cToken2': '',
24 | 'cTokenn': ''
25 | }
26 | }
27 |
28 | /**
29 | * all abi’s that the timelock admin contract interacts with (/timelock/abi)
30 | */
31 |
32 | export const contract_abi_file : any = {
33 | 'unitroller': 'unitroller-abi.json',
34 | 'comptroller': 'comptroller-abi.json',
35 | 'cToken1': 'cToken-abi.json',
36 | 'cToken2': 'cToken-abi.json',
37 | 'cTokenn': 'cToken-abi.json'
38 | }
39 |
40 | /**
41 | * deplay Offset, unit: seconds
42 | */
43 | export const delay_offset = 300;
44 |
45 | /**
46 | * timelock contract address dictionary for mainnet and ropsten (add other chains if necessary, compound addresses * added as example)
47 | */
48 | export const timelock_address : any = {
49 | 1: '0x6d903f6003cca6255D85CcA4D3B5E5146dC33925',
50 | 3: '0x4168FE8179C5e99074068244413909F40c4301B2'
51 | }
52 |
53 | /**
54 | * Timelock admin contact requires the execution of the queueTransaction function using the specified parameters
55 | */
56 |
57 | export const queue_functions : any = {
58 | 'unitroller': ['_acceptAdmin', '_setPendingAdmin', '_setPendingImplementation'],
59 | 'comptroller': ['_become', '_setBorrowPaused', '_setMiningBuff', '_setCompRate', '_setMintPaused', '_supportMarket', '_dropCompMarket', '_setPriceOracle', '_setCollateralFactor'],
60 | 'cToken1': ['_acceptAdmin', '_setReserveFactor'],
61 | 'cToken2': ['_acceptAdmin', '_setReserveFactor'],
62 | 'cTokenn': ['_acceptAdmin', '_setReserveFactor']
63 | }
64 |
65 | ```
66 | ## Run and deploy
67 |
68 | ### Run:
69 |
70 | Execute in the project root directory
71 |
72 | ```shell
73 | yarn
74 | yarn dev
75 | ```
76 |
77 | ### Deploy:
78 |
79 | Execute in the project root directory
80 |
81 | ```shell
82 | yarn build
83 | ```
84 | Deploy the ./dist directory through nginx/apache
85 |
86 | ## Support Languages
87 |
88 | ### [CN](./README-CN.md)
89 |
90 |
--------------------------------------------------------------------------------
/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{ HEAD }}
9 |
10 |
11 |
12 | {{ APP }}
13 |
14 |
15 |
--------------------------------------------------------------------------------
/assets/css/theme-antd.less:
--------------------------------------------------------------------------------
1 | // @import '~ant-design-vue/dist/antd.less'; // 引入官方提供的 less 样式入口文件
2 |
3 | @import '~/node_modules/ant-design-vue/lib/button/style/index.less';
4 | @import '~/node_modules/ant-design-vue/lib/steps/style/index.less';
5 | @import '~/node_modules/ant-design-vue/lib/form/style/index.less';
6 | @import '~/node_modules/ant-design-vue/lib/input/style/index.less';
7 | @import '~/node_modules/ant-design-vue/lib/select/style/index.less';
8 | @import '~/node_modules/ant-design-vue/lib/progress/style/index.less';
9 | @import '~/node_modules/ant-design-vue/lib/avatar/style/index.less';
10 | @import '~/node_modules/ant-design-vue/lib/table/style/index.less';
11 | @import '~/node_modules/ant-design-vue/lib/dropdown/style/index.less';
12 | @import '~/node_modules/ant-design-vue/lib/menu/style/index.less';
13 | @import '~/node_modules/ant-design-vue/lib/message/style/index.less';
14 | @import '~/node_modules/ant-design-vue/lib/modal/style/index.less';
15 | @import '~/node_modules/ant-design-vue/lib/form-model/style/index.less';
16 | @import '~/node_modules/ant-design-vue/lib/drawer/style/index.less';
17 | @import '~/node_modules/ant-design-vue/lib/slider/style/index.less';
18 | @import '~/node_modules/ant-design-vue/lib/switch/style/index.less';
19 | @import '~/node_modules/ant-design-vue/lib/spin/style/index.less';
20 | @import '~/node_modules/ant-design-vue/lib/input-number/style/index.less';
21 | @import '~/node_modules/ant-design-vue/lib/notification/style/index.less';
22 | @import '~/node_modules/ant-design-vue/lib/skeleton/style/index.less';
23 | @import '~/node_modules/ant-design-vue/lib/tooltip/style/index.less';
24 | @import '~/node_modules/ant-design-vue/lib/collapse/style/index.less';
25 | @import '~/node_modules/ant-design-vue/lib/tag/style/index.less';
26 |
27 | .ant-skeleton.ant-skeleton-active
28 | .ant-skeleton-content
29 | .ant-skeleton-paragraph
30 | > li {
31 | background: linear-gradient(90deg, #242424 65%, #262626 47%, #2e2e2e 83%);
32 | background-size: 400% 100%;
33 | -webkit-animation: ant-skeleton-loading 1.4s ease infinite;
34 | animation: ant-skeleton-loading 1.4s ease infinite;
35 | }
36 |
37 | html,
38 | body {
39 | /* 苹方-简 中黑体 */
40 | font-family: PingFangSC-Medium, sans-serif;
41 | font-size: 15px;
42 | word-spacing: 1px;
43 | -ms-text-size-adjust: 100%;
44 | -webkit-text-size-adjust: 100%;
45 | -moz-osx-font-smoothing: grayscale;
46 | -webkit-font-smoothing: antialiased;
47 | box-sizing: border-box;
48 | overflow: auto;
49 | background-color: #080808;
50 | }
51 |
52 | body {
53 | min-height: 100vh;
54 | scroll-behavior: smooth;
55 | text-rendering: optimizeSpeed;
56 | }
57 |
58 | *,
59 | *::before,
60 | *::after {
61 | box-sizing: border-box;
62 | margin: 0;
63 | padding: 0;
64 | }
65 |
66 | /* Box sizing rules */
67 | *,
68 | *::before,
69 | *::after {
70 | box-sizing: border-box;
71 | }
72 |
73 | /* Remove default padding */
74 | ul[class],
75 | ol[class] {
76 | padding: 0;
77 | }
78 |
79 | /* Remove default margin */
80 | body,
81 | h1,
82 | h2,
83 | h3,
84 | h4,
85 | p,
86 | ul[class],
87 | ol[class],
88 | figure,
89 | blockquote,
90 | dl,
91 | dd {
92 | margin: 0;
93 | }
94 |
95 | /* Remove list styles on ul, ol elements with a class attribute */
96 | ul[class],
97 | ol[class] {
98 | list-style: none;
99 | }
100 |
101 | ul,
102 | ol {
103 | list-style: none;
104 | margin: 0;
105 | padding: 0;
106 | }
107 |
108 | p {
109 | margin: 0;
110 | }
111 |
112 | /* A elements that don't have a class get default styles */
113 | a:not([class]) {
114 | text-decoration-skip-ink: auto;
115 | }
116 |
117 | /* Make images easier to work with */
118 | img {
119 | max-width: 100%;
120 | display: block;
121 | }
122 |
123 | /* Natural flow and rhythm in articles by default */
124 | article > * + * {
125 | margin-top: 1em;
126 | }
127 |
128 | /* Inherit fonts for inputs and buttons */
129 | input,
130 | button,
131 | textarea,
132 | select {
133 | font: inherit;
134 | }
135 |
136 | /* Remove all animations and transitions for people that prefer not to see them */
137 | @media (prefers-reduced-motion: reduce) {
138 | * {
139 | animation-duration: 0.01ms !important;
140 | animation-iteration-count: 1 !important;
141 | transition-duration: 0.01ms !important;
142 | scroll-behavior: auto !important;
143 | }
144 | }
145 |
146 | /* 自定义滚动条(chrome) */
147 | .z-scroll::-webkit-scrollbar {
148 | width: 6px;
149 | height: 4px;
150 | background: #eeeeee;
151 | /* 整个滚条背景 */
152 | }
153 |
154 | .z-scroll::-webkit-scrollbar-thumb {
155 | border-radius: 0px;
156 | background: #bbbbbb;
157 | /* 滚条内嵌颜色 */
158 | }
159 |
160 | .z-scroll::-webkit-scrollbar-button {
161 | background-color: #bbbbbb;
162 | width: 0;
163 | height: 0;
164 | /* 两边端按钮颜色 */
165 | }
166 |
167 | *::-webkit-scrollbar {
168 | width: 6px;
169 | height: 4px;
170 | background: #eeeeee;
171 | /* 整个滚条背景 */
172 | }
173 |
174 | *::-webkit-scrollbar-thumb {
175 | border-radius: 0px;
176 | background: #bbbbbb;
177 | /* 滚条内嵌颜色 */
178 | }
179 |
180 | *::-webkit-scrollbar-button {
181 | background-color: #bbbbbb;
182 | width: 0;
183 | height: 0;
184 | /* 两边端按钮颜色 */
185 | }
186 |
187 | /* 布局控制 */
188 | .is-pc {
189 | display: block;
190 | }
191 | .is-mobile {
192 | display: none;
193 | }
194 |
195 |
196 | @media only screen and (max-width: 880px) {
197 | .is-pc {
198 | display: none;
199 | }
200 | .is-mobile {
201 | display: block;
202 | }
203 | .t-default-main--padding {
204 | padding: 0 !important;
205 | }
206 | .ant-modal {
207 | width: 90% !important;
208 | }
209 | }
210 | /* ******** */
211 |
212 | /* antd-reload */
213 | .ant-table-placeholder {
214 | background: transparent;
215 | color: rgba(255, 255, 255, 0.6);
216 | border: none;
217 | }
218 |
219 | .ant-select-dropdown-menu {
220 | border-radius: 2px;
221 |
222 | .ant-select-dropdown-menu-item {
223 | background-color: #000000;
224 | color: #ffffff;
225 | font-size: 14px;
226 | box-sizing: border-box;
227 | padding: 8px 12px;
228 | }
229 | .ant-select-dropdown-menu-item:active {
230 | background-color: rgba(0, 0, 0, 0.9);
231 | }
232 | .ant-select-dropdown-menu-item:hover {
233 | background-color: rgba(0, 0, 0, 0.9);
234 | }
235 | .ant-select-dropdown-menu-item-selected {
236 | background-color: rgba(0, 0, 0, 0.9);
237 | }
238 | }
239 |
240 | .ant-dropdown-menu {
241 | .ant-dropdown-menu-item {
242 | background-color: #000000;
243 | color: #ffffff;
244 | font-size: 14px;
245 | box-sizing: border-box;
246 | padding: 8px 12px;
247 | }
248 | .ant-dropdown-menu-item:active {
249 | background-color: rgba(0, 0, 0, 0.9);
250 | }
251 | .ant-dropdown-menu-item:hover {
252 | background-color: rgba(0, 0, 0, 0.9);
253 | }
254 | }
255 |
256 | .ant-btn-primary {
257 | color: #565656 !important;
258 | }
259 |
260 | /* =========================== */
--------------------------------------------------------------------------------
/assets/css/theme.scss:
--------------------------------------------------------------------------------
1 | /* mixin */
2 | @function vpx($px) {
3 | // @return $px / (19.2) * 1vw;
4 | @return $px * 0.9px;
5 | }
6 |
7 | @function rpx($px) {
8 | @return $px / (7.5) * 1vw;
9 | // @return $px / 2 * 1px;
10 | }
11 |
--------------------------------------------------------------------------------
/assets/img/common/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unizon-blockchain/timelock/0c5788dd7229dc69ff00e81387955470f4c9abcf/assets/img/common/close.png
--------------------------------------------------------------------------------
/build/module/scss.txt:
--------------------------------------------------------------------------------
1 | // scss
--------------------------------------------------------------------------------
/build/module/ts.txt:
--------------------------------------------------------------------------------
1 | import { Vue, Component } from 'vue-property-decorator'
2 |
3 | @Component
4 | class #component# extends Vue {
5 | // props
6 | }
7 |
8 | export default #component#
9 |
--------------------------------------------------------------------------------
/build/module/vue.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/build/page.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const nodePath = require('path')
3 | const color = require('colors')
4 |
5 | const stat = fs.stat;
6 |
7 | console.log('根路径:', process.env.INIT_CWD)
8 |
9 | function pathResolve(path) {
10 | return nodePath.resolve(__dirname, path)
11 | }
12 |
13 | function wrapPromise(fn) {
14 | return new Promise((resolve, reject) => {
15 | fn(resolve, reject)
16 | })
17 | }
18 |
19 | function firstToUpperCase(str) {
20 | return str.replace(str[0], str[0].toUpperCase())
21 | }
22 |
23 | const options = process.argv.splice(2)
24 | const targetPath = options[0]
25 |
26 |
27 | console.log(`\nCreate file: ${targetPath}\n`.green)
28 |
29 | const modulePath = '../build/module'
30 | const outputPath = '../pages'
31 |
32 | let moduleFile = {
33 | vue: `${modulePath}\\vue.txt`,
34 | ts: `${modulePath}\\ts.txt`,
35 | scss: `${modulePath}\\scss.txt`
36 | }
37 |
38 | // yarn p user/login
39 |
40 | const targetPathSplit = targetPath.split('/')
41 |
42 | const fileNamePrefix = outputPath + '/' + (targetPath.indexOf('/') > -1 ? targetPath.substring(0, targetPath.lastIndexOf("/")) : targetPath)
43 | const filename = targetPathSplit.length > 0 ? targetPathSplit[targetPathSplit.length - 1] : targetPath
44 |
45 | const outputFile = {
46 | vue: `${outputPath}\\${targetPath}.vue`,
47 | ts: `${outputPath}\\${targetPath}.ts`,
48 | scss: `${outputPath}\\${targetPath}.scss`
49 | }
50 |
51 | /**
52 | * 替换 vue 模板内容
53 | * @param {*} data
54 | */
55 | function replaceVue(content) {
56 | content = content.replace(/#path#/g, filename)
57 | return content
58 | }
59 |
60 | /**
61 | * 替换模板 ts 内容
62 | * @param {*} data
63 | */
64 | function replaceTs(content) {
65 | content = content.replace(/#component#/g, firstToUpperCase(filename))
66 | return content
67 | }
68 |
69 | /**
70 | * 文件是否已存在
71 | * @param {*} output
72 | */
73 | async function exists(output) {
74 | return await wrapPromise(resolve => {
75 | //测试某个路径下文件是否存在
76 | fs.exists(pathResolve(output), function (exists) {
77 | if (exists) {//存在
78 | resolve(true)
79 | } else {//不存在
80 | resolve(false)
81 | }
82 | })
83 | })
84 | }
85 |
86 | /**
87 | * 创建文件夹
88 | * @param {*} path
89 | */
90 | async function createDir(path) {
91 | return await wrapPromise(resolve => {
92 | fs.mkdir(path, { recursive: true }, (err) => {//创建目录
93 | if (err) {
94 | resolve(false)
95 | }
96 | resolve(true)
97 | })
98 | })
99 | }
100 |
101 | /**
102 | * 读取文件内容
103 | * @param {*} path
104 | */
105 | async function readFile(path) {
106 | return await wrapPromise(resolve => {
107 | fs.readFile(nodePath.join(__dirname, path), 'utf8', (err, data) => {
108 | if (err) { resolve(null) }
109 | resolve(data)
110 | })
111 | })
112 | }
113 |
114 | /**
115 | * 创建并写入文件
116 | * @param {*} path
117 | * @param {*} data
118 | */
119 | async function writeFile(path, data) {
120 | return await wrapPromise(resolve => {
121 | fs.writeFile(nodePath.join(__dirname, path), data, 'utf8', (err) => {
122 | if (err) return false;
123 | resolve(true)
124 | })
125 | })
126 | }
127 |
128 | /**
129 | * 是否存在原文件,true: 替换模板文件路径为已存在文件路径
130 | */
131 | async function isExistsOriginalFile() {
132 | const isVueExists = await exists(outputFile.vue)
133 | moduleFile.vue = isVueExists ? outputFile.vue : moduleFile.vue
134 | const isTsExists = await exists(outputFile.ts)
135 | moduleFile.ts = isTsExists ? outputFile.ts : moduleFile.ts
136 | const isScssExists = await exists(outputFile.scss)
137 | moduleFile.scss = isScssExists ? outputFile.scss : moduleFile.scss
138 | }
139 |
140 | /**
141 | * 数据读取并生成文件
142 | */
143 | async function generateFile() {
144 | await isExistsOriginalFile()
145 | let vuePath = moduleFile.vue
146 | const tsPath = moduleFile.ts
147 | const scssPath = moduleFile.scss
148 |
149 | const vueData = await readFile(vuePath)
150 | vueData && await writeFile(outputFile.vue, replaceVue(vueData))
151 | const tsData = await readFile(tsPath)
152 | tsData && await writeFile(outputFile.ts, replaceTs(tsData))
153 | const scssData = await readFile(scssPath)
154 | scssData && await writeFile(outputFile.scss, scssData)
155 |
156 | return true
157 | }
158 |
159 | /**
160 | * 初始化
161 | */
162 | async function initialize() {
163 | const filePath = pathResolve(`${fileNamePrefix}`)
164 |
165 | const isExists = await exists(filePath)
166 | if (!isExists) {
167 | await createDir(filePath)
168 | }
169 | await generateFile()
170 |
171 | console.log('√ Generated Successful!'.green)
172 | }
173 |
174 | initialize()
--------------------------------------------------------------------------------
/components/business/TransactionDetail.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
20 |
21 | {{ item.executeOrCancelTransaction.decodedFunction.name }}
22 |
23 |
24 | Block Number:
25 | {{ item.executeOrCancelTransaction.blockNumber }}
27 | |
28 |
29 | {{ item.executeOrCancelTransaction.timestamp | parseLocalDateTime }}
30 |
31 |
32 |
33 |
41 |
42 |
43 |
44 |
{{ item.decodedFunction.name }}
45 |
46 | Block Number: {{ item.blockNumber }} |
47 | {{ item.timestamp | parseLocalDateTime }}
48 |
49 |
50 |
58 |
59 |
60 |
64 |
{{ 'Cancel Transaction' }}
71 |
{{ 'Execute Transaction' }}
78 |
79 |
80 |
81 |
82 |
83 |
192 |
193 |
--------------------------------------------------------------------------------
/components/ui/ZonCard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/components/ui/ZonModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
20 | {{ title }}
21 |
22 |
23 |
24 |
38 |
41 |
42 |
43 |
44 |
71 |
72 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | moduleNameMapper: {
3 | '^@/(.*)$': '/$1',
4 | '^~/(.*)$': '/$1',
5 | '^vue$': 'vue/dist/vue.common.js',
6 | },
7 | moduleFileExtensions: ['ts', 'js', 'vue', 'json'],
8 | transform: {
9 | '^.+\\.ts$': 'ts-jest',
10 | '^.+\\.js$': 'babel-jest',
11 | '.*\\.(vue)$': 'vue-jest',
12 | },
13 | collectCoverage: true,
14 | collectCoverageFrom: [
15 | '/components/**/*.vue',
16 | '/pages/**/*.vue',
17 | ],
18 | }
19 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "paths": {
5 | "~/*": ["./*"],
6 | "@/*": ["./*"],
7 | "~~/*": ["./*"],
8 | "@@/*": ["./*"]
9 | }
10 | },
11 | "exclude": ["node_modules", ".nuxt", "dist"]
12 | }
13 |
--------------------------------------------------------------------------------
/layouts/default.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ 'Unizon Timelock Admin' }}
5 |
6 |
7 |
8 |
9 |
10 |
22 |
44 |
94 |
--------------------------------------------------------------------------------
/nuxt.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | /*
3 | ** Nuxt rendering mode
4 | ** See https://nuxtjs.org/api/configuration-mode
5 | */
6 | mode: 'spa',
7 | /*
8 | ** Nuxt target
9 | ** See https://nuxtjs.org/api/configuration-target
10 | */
11 | target: 'server',
12 | /*
13 | ** Headers of the page
14 | ** See https://nuxtjs.org/api/configuration-head
15 | */
16 | server: {
17 | port: 3001, // default: 3000
18 | host: '0.0.0.0' // default: localhost,
19 | },
20 | head: {
21 | title: 'Unizon Timelock Admin',
22 | meta: [
23 | { charset: 'utf-8' },
24 | { name: 'viewport', content: 'width=device-width, initial-scale=1' },
25 | {
26 | hid: 'description',
27 | name: 'description',
28 | content: process.env.npm_package_description || '',
29 | },
30 | ],
31 | link: [
32 | { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
33 | ],
34 | // vendor: ['vue-i18n'],
35 | },
36 | /*
37 | ** Global CSS
38 | */
39 | css: [
40 | '@/assets/css/theme-antd.less'
41 | ],
42 | /**
43 | * global scss
44 | */
45 | styleResources: {
46 | scss: './assets/css/theme.scss',
47 | },
48 | /*
49 | ** Plugins to load before mounting the App
50 | ** https://nuxtjs.org/guide/plugins
51 | */
52 | plugins: [
53 | '@/plugins/polyfill.ts',
54 | '@/plugins/antd-ui.js',
55 | '@/plugins/filter.ts',
56 | '@/plugins/app.ts',
57 | ],
58 | /*
59 | ** Auto import components
60 | ** See https://nuxtjs.org/api/configuration-components
61 | */
62 | components: true,
63 | /*
64 | ** Nuxt.js dev-modules
65 | */
66 | buildModules: ['@nuxt/typescript-build'],
67 | /*
68 | ** Nuxt.js modules
69 | */
70 | modules: [
71 | // Doc: https://axios.nuxtjs.org/usage
72 | '@nuxtjs/axios',
73 | '@nuxtjs/style-resources'
74 | ],
75 | /*
76 | ** Axios module configuration
77 | ** See https://axios.nuxtjs.org/options
78 | */
79 | axios: {},
80 | /*
81 | ** Build configuration
82 | ** See https://nuxtjs.org/api/configuration-build/
83 | */
84 | build: {
85 | analyze: false,
86 | assetFilter: function (assetFilename) {
87 | return assetFilename.endsWith('.js');
88 | },
89 | maxChunkSize: 30000,
90 | loaders: {
91 | less: {
92 | lessOptions: {
93 | javascriptEnabled: true,
94 | modifyVars: {
95 | 'primary-color': '#ddbd31'
96 | }
97 | }
98 | }
99 | },
100 | extend (config, { isDev, isClient }) {
101 | if (isClient && !isDev) {
102 | config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
103 | }
104 | }
105 | },
106 | loading: false,
107 | resourceHints: false
108 | }
109 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "unizon-timelock-admin",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "nuxt",
7 | "build": "nuxt-ts build",
8 | "start": "nuxt-ts start",
9 | "export": "nuxt-ts export",
10 | "serve": "nuxt-ts serve",
11 | "lint:js": "eslint --ext .js,.vue --ignore-path .gitignore .",
12 | "lint": "yarn lint:js",
13 | "test": "jest",
14 | "page": "node build/page.js user/login",
15 | "p": "node build/page.js"
16 | },
17 | "dependencies": {
18 | "@nuxt/typescript-runtime": "^0.4.10",
19 | "@nuxtjs/axios": "^5.11.0",
20 | "abi-decoder": "^2.3.0",
21 | "ant-design-vue": "^1.6.4",
22 | "bignumber.js": "^9.0.1",
23 | "date-fns": "^2.16.1",
24 | "ethers": "^5.0.14",
25 | "nuxt": "^2.13.0",
26 | "vue-i18n": "^8.21.0",
27 | "vue-rx": "^6.2.0"
28 | },
29 | "devDependencies": {
30 | "@nuxt/typescript-build": "^1.0.3",
31 | "@nuxtjs/eslint-config": "^3.0.0",
32 | "@nuxtjs/eslint-config-typescript": "^2.0.0",
33 | "@nuxtjs/eslint-module": "^2.0.0",
34 | "@nuxtjs/style-resources": "^1.0.0",
35 | "@vue/test-utils": "^1.0.3",
36 | "antd-scss-theme-plugin": "^1.0.8",
37 | "babel-core": "7.0.0-bridge.0",
38 | "babel-eslint": "^10.1.0",
39 | "babel-jest": "^26.0.1",
40 | "babel-polyfill": "^6.26.0",
41 | "babel-preset-stage-3": "^6.24.1",
42 | "dart-sass": "^1.25.0",
43 | "eslint": "^7.2.0",
44 | "eslint-config-prettier": "^6.11.0",
45 | "eslint-plugin-nuxt": "^1.0.0",
46 | "eslint-plugin-prettier": "^3.1.4",
47 | "jest": "^26.0.1",
48 | "less": "^3.12.2",
49 | "less-loader": "^6.2.0",
50 | "prettier": "^2.0.5",
51 | "sass": "^1.26.10",
52 | "sass-loader": "^9.0.3",
53 | "ts-jest": "^26.1.0",
54 | "vue-class-component": "^7.2.5",
55 | "vue-jest": "^3.0.4",
56 | "vue-property-decorator": "^9.0.0"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
18 |
19 |
28 |
29 |
30 |
31 | {{ from }}
32 |
33 | {{ from | addressFormat }}
34 |
35 |
36 |
37 | {{ record.timestamp | parseLocalDateTime }}
38 |
39 |
40 |
{{ record.targetInfo }}
41 |
42 |
43 | {{
44 | handleTargetAddress(record.decodedFunction.params, false)
45 | }}
46 |
47 |
48 | {{ handleTargetAddress(record.decodedFunction.params) }}
49 |
50 |
51 |
52 |
53 |
54 | {{ handleMethod(record.decodedFunction.params) }}
55 |
56 |
57 |
58 |
62 | {{ item.isQueued ? 'Pending' : 'Finished' }}
63 |
64 |
68 | {{ 'View on etherscan' }}
69 |
70 |
71 |
72 |
73 |
74 |
78 |
79 |
80 |
81 |
220 |
221 |
239 |
--------------------------------------------------------------------------------
/pages/newTransaction.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
21 |
22 |
{{
23 | 'Queue'
24 | }}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
84 |
85 |
--------------------------------------------------------------------------------
/pages/tokenContract.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 | {{tokenContract.name}}{{tokenContract.address ? '| ' + tokenContract.address : '' }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
{{ input.name }}({{ input.type }})
24 |
28 |
29 |
30 |
{{ 'Queue' }}
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
149 |
150 |
--------------------------------------------------------------------------------
/plugins/antd-ui.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | import {
4 | Button,
5 | Steps,
6 | Form,
7 | Input,
8 | Select,
9 | Progress,
10 | Avatar,
11 | Row,
12 | Col,
13 | Table,
14 | Menu,
15 | Dropdown,
16 | Icon,
17 | Modal,
18 | FormModel,
19 | Drawer,
20 | Slider,
21 | Switch,
22 | Spin,
23 | InputNumber,
24 | Skeleton,
25 | Tooltip,
26 | Popconfirm,
27 | Collapse,
28 | message,
29 | notification,
30 | Tag
31 | } from 'ant-design-vue'
32 |
33 | import 'ant-design-vue/lib/row/style'
34 | import 'ant-design-vue/lib/col/style'
35 | import 'ant-design-vue/lib/popconfirm/style'
36 |
37 | Vue.use(Button)
38 | Vue.use(Steps) // 步骤条
39 | Vue.use(Form)
40 | Vue.use(Form.Item)
41 | Vue.use(Input)
42 | Vue.use(Select)
43 | Vue.use(Progress)
44 | Vue.use(Avatar)
45 | Vue.use(Row)
46 | Vue.use(Col)
47 | Vue.use(Table)
48 | Vue.use(Menu)
49 | Vue.use(Dropdown)
50 | Vue.use(Icon)
51 | Vue.use(Modal)
52 | Vue.use(FormModel)
53 | Vue.use(FormModel.Item)
54 | Vue.use(Drawer)
55 | Vue.use(Slider)
56 | Vue.use(Switch)
57 | Vue.use(Skeleton)
58 | Vue.use(Spin)
59 | Vue.use(InputNumber)
60 | Vue.use(Tooltip)
61 | Vue.use(Popconfirm)
62 | Vue.use(Collapse)
63 | Vue.use(Tag)
64 |
65 | Vue.prototype.$message = message
66 | Vue.prototype.$notification = notification
--------------------------------------------------------------------------------
/plugins/app.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import EthereumProvider from '~/timelock/provider';
3 |
4 | declare module 'vue/types/vue' {
5 | interface Vue {
6 | $useEthereumProvider(callback: any): void;
7 | $ethereumProvider: EthereumProvider;
8 | $useConnectWallet(): void;
9 | $getEtherScanUrl(txHash: any): string;
10 | $getNetworkName(): string;
11 | }
12 | }
13 |
14 | let ethereumProvider: EthereumProvider;
15 |
16 | export default ({ app, store }: any) => {
17 | if ('undefined' === typeof ethereumProvider) {
18 | ethereumProvider = new EthereumProvider();
19 | }
20 |
21 | async function useConnectWallet() {
22 | const account: string | null = await ethereumProvider.connect();
23 | store.commit('SET_ACCOUNT', account);
24 | }
25 |
26 | Vue.prototype.$useConnectWallet = useConnectWallet;
27 |
28 | Vue.prototype.$useEthereumProvider = async function (callback: any) {
29 | try {
30 | ethereumProvider.monitor({
31 | accountChanged: async (account: any) => {
32 | store.commit('SET_ACCOUNT', account);
33 | 'function' === typeof callback && callback();
34 | },
35 | chainChanged: async (chainId: any) => {
36 | store.commit('SET_CHAIN_ID', chainId);
37 | 'function' === typeof callback && callback();
38 | },
39 | });
40 |
41 | Vue.prototype.$ethereumProvider = ethereumProvider;
42 |
43 | useConnectWallet();
44 | } catch (e) {}
45 | }
46 |
47 | Vue.prototype.$getEtherScanUrl = function(txHash: any): string {
48 | let res : string = `https://etherscan.io/tx/${txHash}`;
49 |
50 | if(3 == ethereumProvider.chainId) {
51 | res = `https://ropsten.etherscan.io/tx/${txHash}`;
52 | }
53 | if(4 == ethereumProvider.chainId) {
54 | res = `https://rinkeby.etherscan.io/tx/${txHash}`;
55 | }
56 | if(42 == ethereumProvider.chainId) {
57 | res = `https://kovan.etherscan.io/tx/${txHash}`;
58 | }
59 |
60 | return res;
61 | }
62 |
63 | Vue.prototype.$getNetworkName = function() {
64 | let res : string = '';
65 | switch(ethereumProvider.chainId) {
66 | case 1:
67 | res = '';
68 | break;
69 | case 3:
70 | res = 'ropsten';
71 | break;
72 | case 4:
73 | res = 'rinkeby';
74 | break;
75 | case 42:
76 | res = 'kovan';
77 | break;
78 | default:
79 | res = 'unknown';
80 | break;
81 | }
82 |
83 | return res;
84 | }
85 |
86 |
87 | };
88 |
--------------------------------------------------------------------------------
/plugins/filter.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from 'vue-property-decorator'
2 |
3 | declare module 'vue/types/vue' {
4 | interface Vue {
5 | $filter: any
6 | }
7 | }
8 |
9 | export default ({ app, store }: any) => {
10 | Vue.filter('parseLocalDateTime', function (value: number) {
11 | const dt = new Date(value * 1000);
12 | return dt.toUTCString();
13 | })
14 |
15 | const addressFormat = (value: string, Digits: number = 4) => {
16 | let data =
17 | '0x' +
18 | value.toString().substring(2, Digits + 2) +
19 | '...' +
20 | value.substring(value.length, value.length - Digits)
21 | return data
22 | }
23 | Vue.filter('addressFormat', addressFormat)
24 |
25 | Vue.prototype.$filter = {
26 | addressFormat
27 | }
28 | }
--------------------------------------------------------------------------------
/plugins/polyfill.ts:
--------------------------------------------------------------------------------
1 | import 'babel-polyfill'
2 |
--------------------------------------------------------------------------------
/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unizon-blockchain/timelock/0c5788dd7229dc69ff00e81387955470f4c9abcf/static/favicon.ico
--------------------------------------------------------------------------------
/store/contract.ts:
--------------------------------------------------------------------------------
1 | import { ITokenContract } from '~/timelock/interface';
2 |
3 | export const state = () => ({
4 | tokenContract: {}
5 | })
6 |
7 | export const mutations = {
8 | SET_TOKEN_CONTRACT(state: any, value: ITokenContract) {
9 | state.tokenContract = { ...value };
10 | }
11 | }
--------------------------------------------------------------------------------
/store/index.ts:
--------------------------------------------------------------------------------
1 | export const state = () => ({
2 | account: '',
3 | chainId: ''
4 | })
5 | export const mutations = {
6 | SET_ACCOUNT(state: any, account: any): void {
7 | state.account = account || ''
8 | },
9 | SET_CHAIN_ID(state: any, chainId: any): void {
10 | state.chainId = chainId || ''
11 | },
12 | }
13 |
--------------------------------------------------------------------------------
/test/Logo.spec.js:
--------------------------------------------------------------------------------
1 | import { mount } from '@vue/test-utils'
2 | import Logo from '@/components/Logo.vue'
3 |
4 | describe('Logo', () => {
5 | test('is a Vue instance', () => {
6 | const wrapper = mount(Logo)
7 | expect(wrapper.vm).toBeTruthy()
8 | })
9 | })
10 |
--------------------------------------------------------------------------------
/timelock/abi/cETH-abi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "constant":true,
4 | "inputs":[
5 |
6 | ],
7 | "name":"name",
8 | "outputs":[
9 | {
10 | "name":"",
11 | "type":"string"
12 | }
13 | ],
14 | "payable":false,
15 | "stateMutability":"view",
16 | "type":"function",
17 | "signature":"0x06fdde03"
18 | },
19 | {
20 | "constant":false,
21 | "inputs":[
22 | {
23 | "name":"spender",
24 | "type":"address"
25 | },
26 | {
27 | "name":"amount",
28 | "type":"uint256"
29 | }
30 | ],
31 | "name":"approve",
32 | "outputs":[
33 | {
34 | "name":"",
35 | "type":"bool"
36 | }
37 | ],
38 | "payable":false,
39 | "stateMutability":"nonpayable",
40 | "type":"function",
41 | "signature":"0x095ea7b3"
42 | },
43 | {
44 | "constant":false,
45 | "inputs":[
46 |
47 | ],
48 | "name":"mint",
49 | "outputs":[
50 |
51 | ],
52 | "payable":true,
53 | "stateMutability":"payable",
54 | "type":"function",
55 | "signature":"0x1249c58b"
56 | },
57 | {
58 | "constant":true,
59 | "inputs":[
60 |
61 | ],
62 | "name":"reserveFactorMantissa",
63 | "outputs":[
64 | {
65 | "name":"",
66 | "type":"uint256"
67 | }
68 | ],
69 | "payable":false,
70 | "stateMutability":"view",
71 | "type":"function",
72 | "signature":"0x173b9904"
73 | },
74 | {
75 | "constant":false,
76 | "inputs":[
77 | {
78 | "name":"account",
79 | "type":"address"
80 | }
81 | ],
82 | "name":"borrowBalanceCurrent",
83 | "outputs":[
84 | {
85 | "name":"",
86 | "type":"uint256"
87 | }
88 | ],
89 | "payable":false,
90 | "stateMutability":"nonpayable",
91 | "type":"function",
92 | "signature":"0x17bfdfbc"
93 | },
94 | {
95 | "constant":true,
96 | "inputs":[
97 |
98 | ],
99 | "name":"totalSupply",
100 | "outputs":[
101 | {
102 | "name":"",
103 | "type":"uint256"
104 | }
105 | ],
106 | "payable":false,
107 | "stateMutability":"view",
108 | "type":"function",
109 | "signature":"0x18160ddd"
110 | },
111 | {
112 | "constant":true,
113 | "inputs":[
114 |
115 | ],
116 | "name":"exchangeRateStored",
117 | "outputs":[
118 | {
119 | "name":"",
120 | "type":"uint256"
121 | }
122 | ],
123 | "payable":false,
124 | "stateMutability":"view",
125 | "type":"function",
126 | "signature":"0x182df0f5"
127 | },
128 | {
129 | "constant":false,
130 | "inputs":[
131 | {
132 | "name":"src",
133 | "type":"address"
134 | },
135 | {
136 | "name":"dst",
137 | "type":"address"
138 | },
139 | {
140 | "name":"amount",
141 | "type":"uint256"
142 | }
143 | ],
144 | "name":"transferFrom",
145 | "outputs":[
146 | {
147 | "name":"",
148 | "type":"bool"
149 | }
150 | ],
151 | "payable":false,
152 | "stateMutability":"nonpayable",
153 | "type":"function",
154 | "signature":"0x23b872dd"
155 | },
156 | {
157 | "constant":true,
158 | "inputs":[
159 |
160 | ],
161 | "name":"pendingAdmin",
162 | "outputs":[
163 | {
164 | "name":"",
165 | "type":"address"
166 | }
167 | ],
168 | "payable":false,
169 | "stateMutability":"view",
170 | "type":"function",
171 | "signature":"0x26782247"
172 | },
173 | {
174 | "constant":true,
175 | "inputs":[
176 |
177 | ],
178 | "name":"decimals",
179 | "outputs":[
180 | {
181 | "name":"",
182 | "type":"uint256"
183 | }
184 | ],
185 | "payable":false,
186 | "stateMutability":"view",
187 | "type":"function",
188 | "signature":"0x313ce567"
189 | },
190 | {
191 | "constant":false,
192 | "inputs":[
193 | {
194 | "name":"owner",
195 | "type":"address"
196 | }
197 | ],
198 | "name":"balanceOfUnderlying",
199 | "outputs":[
200 | {
201 | "name":"",
202 | "type":"uint256"
203 | }
204 | ],
205 | "payable":false,
206 | "stateMutability":"nonpayable",
207 | "type":"function",
208 | "signature":"0x3af9e669"
209 | },
210 | {
211 | "constant":true,
212 | "inputs":[
213 |
214 | ],
215 | "name":"getCash",
216 | "outputs":[
217 | {
218 | "name":"",
219 | "type":"uint256"
220 | }
221 | ],
222 | "payable":false,
223 | "stateMutability":"view",
224 | "type":"function",
225 | "signature":"0x3b1d21a2"
226 | },
227 | {
228 | "constant":false,
229 | "inputs":[
230 | {
231 | "name":"newComptroller",
232 | "type":"address"
233 | }
234 | ],
235 | "name":"_setComptroller",
236 | "outputs":[
237 | {
238 | "name":"",
239 | "type":"uint256"
240 | }
241 | ],
242 | "payable":false,
243 | "stateMutability":"nonpayable",
244 | "type":"function",
245 | "signature":"0x4576b5db"
246 | },
247 | {
248 | "constant":true,
249 | "inputs":[
250 |
251 | ],
252 | "name":"totalBorrows",
253 | "outputs":[
254 | {
255 | "name":"",
256 | "type":"uint256"
257 | }
258 | ],
259 | "payable":false,
260 | "stateMutability":"view",
261 | "type":"function",
262 | "signature":"0x47bd3718"
263 | },
264 | {
265 | "constant":false,
266 | "inputs":[
267 |
268 | ],
269 | "name":"repayBorrow",
270 | "outputs":[
271 |
272 | ],
273 | "payable":true,
274 | "stateMutability":"payable",
275 | "type":"function",
276 | "signature":"0x4e4d9fea"
277 | },
278 | {
279 | "constant":true,
280 | "inputs":[
281 |
282 | ],
283 | "name":"comptroller",
284 | "outputs":[
285 | {
286 | "name":"",
287 | "type":"address"
288 | }
289 | ],
290 | "payable":false,
291 | "stateMutability":"view",
292 | "type":"function",
293 | "signature":"0x5fe3b567"
294 | },
295 | {
296 | "constant":false,
297 | "inputs":[
298 | {
299 | "name":"reduceAmount",
300 | "type":"uint256"
301 | }
302 | ],
303 | "name":"_reduceReserves",
304 | "outputs":[
305 | {
306 | "name":"",
307 | "type":"uint256"
308 | }
309 | ],
310 | "payable":false,
311 | "stateMutability":"nonpayable",
312 | "type":"function",
313 | "signature":"0x601a0bf1"
314 | },
315 | {
316 | "constant":true,
317 | "inputs":[
318 |
319 | ],
320 | "name":"initialExchangeRateMantissa",
321 | "outputs":[
322 | {
323 | "name":"",
324 | "type":"uint256"
325 | }
326 | ],
327 | "payable":false,
328 | "stateMutability":"view",
329 | "type":"function",
330 | "signature":"0x675d972c"
331 | },
332 | {
333 | "constant":true,
334 | "inputs":[
335 |
336 | ],
337 | "name":"accrualBlockNumber",
338 | "outputs":[
339 | {
340 | "name":"",
341 | "type":"uint256"
342 | }
343 | ],
344 | "payable":false,
345 | "stateMutability":"view",
346 | "type":"function",
347 | "signature":"0x6c540baf"
348 | },
349 | {
350 | "constant":true,
351 | "inputs":[
352 | {
353 | "name":"owner",
354 | "type":"address"
355 | }
356 | ],
357 | "name":"balanceOf",
358 | "outputs":[
359 | {
360 | "name":"",
361 | "type":"uint256"
362 | }
363 | ],
364 | "payable":false,
365 | "stateMutability":"view",
366 | "type":"function",
367 | "signature":"0x70a08231"
368 | },
369 | {
370 | "constant":false,
371 | "inputs":[
372 |
373 | ],
374 | "name":"totalBorrowsCurrent",
375 | "outputs":[
376 | {
377 | "name":"",
378 | "type":"uint256"
379 | }
380 | ],
381 | "payable":false,
382 | "stateMutability":"nonpayable",
383 | "type":"function",
384 | "signature":"0x73acee98"
385 | },
386 | {
387 | "constant":false,
388 | "inputs":[
389 | {
390 | "name":"redeemAmount",
391 | "type":"uint256"
392 | }
393 | ],
394 | "name":"redeemUnderlying",
395 | "outputs":[
396 | {
397 | "name":"",
398 | "type":"uint256"
399 | }
400 | ],
401 | "payable":false,
402 | "stateMutability":"nonpayable",
403 | "type":"function",
404 | "signature":"0x852a12e3"
405 | },
406 | {
407 | "constant":true,
408 | "inputs":[
409 |
410 | ],
411 | "name":"totalReserves",
412 | "outputs":[
413 | {
414 | "name":"",
415 | "type":"uint256"
416 | }
417 | ],
418 | "payable":false,
419 | "stateMutability":"view",
420 | "type":"function",
421 | "signature":"0x8f840ddd"
422 | },
423 | {
424 | "constant":true,
425 | "inputs":[
426 |
427 | ],
428 | "name":"symbol",
429 | "outputs":[
430 | {
431 | "name":"",
432 | "type":"string"
433 | }
434 | ],
435 | "payable":false,
436 | "stateMutability":"view",
437 | "type":"function",
438 | "signature":"0x95d89b41"
439 | },
440 | {
441 | "constant":true,
442 | "inputs":[
443 | {
444 | "name":"account",
445 | "type":"address"
446 | }
447 | ],
448 | "name":"borrowBalanceStored",
449 | "outputs":[
450 | {
451 | "name":"",
452 | "type":"uint256"
453 | }
454 | ],
455 | "payable":false,
456 | "stateMutability":"view",
457 | "type":"function",
458 | "signature":"0x95dd9193"
459 | },
460 | {
461 | "constant":false,
462 | "inputs":[
463 |
464 | ],
465 | "name":"accrueInterest",
466 | "outputs":[
467 | {
468 | "name":"",
469 | "type":"uint256"
470 | }
471 | ],
472 | "payable":false,
473 | "stateMutability":"nonpayable",
474 | "type":"function",
475 | "signature":"0xa6afed95"
476 | },
477 | {
478 | "constant":false,
479 | "inputs":[
480 | {
481 | "name":"dst",
482 | "type":"address"
483 | },
484 | {
485 | "name":"amount",
486 | "type":"uint256"
487 | }
488 | ],
489 | "name":"transfer",
490 | "outputs":[
491 | {
492 | "name":"",
493 | "type":"bool"
494 | }
495 | ],
496 | "payable":false,
497 | "stateMutability":"nonpayable",
498 | "type":"function",
499 | "signature":"0xa9059cbb"
500 | },
501 | {
502 | "constant":true,
503 | "inputs":[
504 |
505 | ],
506 | "name":"borrowIndex",
507 | "outputs":[
508 | {
509 | "name":"",
510 | "type":"uint256"
511 | }
512 | ],
513 | "payable":false,
514 | "stateMutability":"view",
515 | "type":"function",
516 | "signature":"0xaa5af0fd"
517 | },
518 | {
519 | "constant":false,
520 | "inputs":[
521 | {
522 | "name":"borrower",
523 | "type":"address"
524 | },
525 | {
526 | "name":"cTokenCollateral",
527 | "type":"address"
528 | }
529 | ],
530 | "name":"liquidateBorrow",
531 | "outputs":[
532 |
533 | ],
534 | "payable":true,
535 | "stateMutability":"payable",
536 | "type":"function",
537 | "signature":"0xaae40a2a"
538 | },
539 | {
540 | "constant":true,
541 | "inputs":[
542 |
543 | ],
544 | "name":"supplyRatePerBlock",
545 | "outputs":[
546 | {
547 | "name":"",
548 | "type":"uint256"
549 | }
550 | ],
551 | "payable":false,
552 | "stateMutability":"view",
553 | "type":"function",
554 | "signature":"0xae9d70b0"
555 | },
556 | {
557 | "constant":false,
558 | "inputs":[
559 | {
560 | "name":"liquidator",
561 | "type":"address"
562 | },
563 | {
564 | "name":"borrower",
565 | "type":"address"
566 | },
567 | {
568 | "name":"seizeTokens",
569 | "type":"uint256"
570 | }
571 | ],
572 | "name":"seize",
573 | "outputs":[
574 | {
575 | "name":"",
576 | "type":"uint256"
577 | }
578 | ],
579 | "payable":false,
580 | "stateMutability":"nonpayable",
581 | "type":"function",
582 | "signature":"0xb2a02ff1"
583 | },
584 | {
585 | "constant":false,
586 | "inputs":[
587 | {
588 | "name":"newPendingAdmin",
589 | "type":"address"
590 | }
591 | ],
592 | "name":"_setPendingAdmin",
593 | "outputs":[
594 | {
595 | "name":"",
596 | "type":"uint256"
597 | }
598 | ],
599 | "payable":false,
600 | "stateMutability":"nonpayable",
601 | "type":"function",
602 | "signature":"0xb71d1a0c"
603 | },
604 | {
605 | "constant":false,
606 | "inputs":[
607 |
608 | ],
609 | "name":"exchangeRateCurrent",
610 | "outputs":[
611 | {
612 | "name":"",
613 | "type":"uint256"
614 | }
615 | ],
616 | "payable":false,
617 | "stateMutability":"nonpayable",
618 | "type":"function",
619 | "signature":"0xbd6d894d"
620 | },
621 | {
622 | "constant":true,
623 | "inputs":[
624 | {
625 | "name":"account",
626 | "type":"address"
627 | }
628 | ],
629 | "name":"getAccountSnapshot",
630 | "outputs":[
631 | {
632 | "name":"",
633 | "type":"uint256"
634 | },
635 | {
636 | "name":"",
637 | "type":"uint256"
638 | },
639 | {
640 | "name":"",
641 | "type":"uint256"
642 | },
643 | {
644 | "name":"",
645 | "type":"uint256"
646 | }
647 | ],
648 | "payable":false,
649 | "stateMutability":"view",
650 | "type":"function",
651 | "signature":"0xc37f68e2"
652 | },
653 | {
654 | "constant":false,
655 | "inputs":[
656 | {
657 | "name":"borrowAmount",
658 | "type":"uint256"
659 | }
660 | ],
661 | "name":"borrow",
662 | "outputs":[
663 | {
664 | "name":"",
665 | "type":"uint256"
666 | }
667 | ],
668 | "payable":false,
669 | "stateMutability":"nonpayable",
670 | "type":"function",
671 | "signature":"0xc5ebeaec"
672 | },
673 | {
674 | "constant":false,
675 | "inputs":[
676 | {
677 | "name":"redeemTokens",
678 | "type":"uint256"
679 | }
680 | ],
681 | "name":"redeem",
682 | "outputs":[
683 | {
684 | "name":"",
685 | "type":"uint256"
686 | }
687 | ],
688 | "payable":false,
689 | "stateMutability":"nonpayable",
690 | "type":"function",
691 | "signature":"0xdb006a75"
692 | },
693 | {
694 | "constant":true,
695 | "inputs":[
696 | {
697 | "name":"owner",
698 | "type":"address"
699 | },
700 | {
701 | "name":"spender",
702 | "type":"address"
703 | }
704 | ],
705 | "name":"allowance",
706 | "outputs":[
707 | {
708 | "name":"",
709 | "type":"uint256"
710 | }
711 | ],
712 | "payable":false,
713 | "stateMutability":"view",
714 | "type":"function",
715 | "signature":"0xdd62ed3e"
716 | },
717 | {
718 | "constant":false,
719 | "inputs":[
720 | {
721 | "name":"borrower",
722 | "type":"address"
723 | }
724 | ],
725 | "name":"repayBorrowBehalf",
726 | "outputs":[
727 |
728 | ],
729 | "payable":true,
730 | "stateMutability":"payable",
731 | "type":"function",
732 | "signature":"0xe5974619"
733 | },
734 | {
735 | "constant":false,
736 | "inputs":[
737 |
738 | ],
739 | "name":"_acceptAdmin",
740 | "outputs":[
741 | {
742 | "name":"",
743 | "type":"uint256"
744 | }
745 | ],
746 | "payable":false,
747 | "stateMutability":"nonpayable",
748 | "type":"function",
749 | "signature":"0xe9c714f2"
750 | },
751 | {
752 | "constant":false,
753 | "inputs":[
754 | {
755 | "name":"newInterestRateModel",
756 | "type":"address"
757 | }
758 | ],
759 | "name":"_setInterestRateModel",
760 | "outputs":[
761 | {
762 | "name":"",
763 | "type":"uint256"
764 | }
765 | ],
766 | "payable":false,
767 | "stateMutability":"nonpayable",
768 | "type":"function",
769 | "signature":"0xf2b3abbd"
770 | },
771 | {
772 | "constant":true,
773 | "inputs":[
774 |
775 | ],
776 | "name":"interestRateModel",
777 | "outputs":[
778 | {
779 | "name":"",
780 | "type":"address"
781 | }
782 | ],
783 | "payable":false,
784 | "stateMutability":"view",
785 | "type":"function",
786 | "signature":"0xf3fdb15a"
787 | },
788 | {
789 | "constant":true,
790 | "inputs":[
791 |
792 | ],
793 | "name":"admin",
794 | "outputs":[
795 | {
796 | "name":"",
797 | "type":"address"
798 | }
799 | ],
800 | "payable":false,
801 | "stateMutability":"view",
802 | "type":"function",
803 | "signature":"0xf851a440"
804 | },
805 | {
806 | "constant":true,
807 | "inputs":[
808 |
809 | ],
810 | "name":"borrowRatePerBlock",
811 | "outputs":[
812 | {
813 | "name":"",
814 | "type":"uint256"
815 | }
816 | ],
817 | "payable":false,
818 | "stateMutability":"view",
819 | "type":"function",
820 | "signature":"0xf8f9da28"
821 | },
822 | {
823 | "constant":false,
824 | "inputs":[
825 | {
826 | "name":"newReserveFactorMantissa",
827 | "type":"uint256"
828 | }
829 | ],
830 | "name":"_setReserveFactor",
831 | "outputs":[
832 | {
833 | "name":"",
834 | "type":"uint256"
835 | }
836 | ],
837 | "payable":false,
838 | "stateMutability":"nonpayable",
839 | "type":"function",
840 | "signature":"0xfca7820b"
841 | },
842 | {
843 | "constant":true,
844 | "inputs":[
845 |
846 | ],
847 | "name":"isCToken",
848 | "outputs":[
849 | {
850 | "name":"",
851 | "type":"bool"
852 | }
853 | ],
854 | "payable":false,
855 | "stateMutability":"view",
856 | "type":"function",
857 | "signature":"0xfe9c44ae"
858 | },
859 | {
860 | "inputs":[
861 | {
862 | "name":"comptroller_",
863 | "type":"address"
864 | },
865 | {
866 | "name":"interestRateModel_",
867 | "type":"address"
868 | },
869 | {
870 | "name":"initialExchangeRateMantissa_",
871 | "type":"uint256"
872 | },
873 | {
874 | "name":"name_",
875 | "type":"string"
876 | },
877 | {
878 | "name":"symbol_",
879 | "type":"string"
880 | },
881 | {
882 | "name":"decimals_",
883 | "type":"uint256"
884 | }
885 | ],
886 | "payable":false,
887 | "stateMutability":"nonpayable",
888 | "type":"constructor",
889 | "signature":"constructor"
890 | },
891 | {
892 | "payable":true,
893 | "stateMutability":"payable",
894 | "type":"fallback"
895 | },
896 | {
897 | "anonymous":false,
898 | "inputs":[
899 | {
900 | "indexed":false,
901 | "name":"interestAccumulated",
902 | "type":"uint256"
903 | },
904 | {
905 | "indexed":false,
906 | "name":"borrowIndex",
907 | "type":"uint256"
908 | },
909 | {
910 | "indexed":false,
911 | "name":"totalBorrows",
912 | "type":"uint256"
913 | }
914 | ],
915 | "name":"AccrueInterest",
916 | "type":"event",
917 | "signature":"0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9"
918 | },
919 | {
920 | "anonymous":false,
921 | "inputs":[
922 | {
923 | "indexed":false,
924 | "name":"minter",
925 | "type":"address"
926 | },
927 | {
928 | "indexed":false,
929 | "name":"mintAmount",
930 | "type":"uint256"
931 | },
932 | {
933 | "indexed":false,
934 | "name":"mintTokens",
935 | "type":"uint256"
936 | }
937 | ],
938 | "name":"Mint",
939 | "type":"event",
940 | "signature":"0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f"
941 | },
942 | {
943 | "anonymous":false,
944 | "inputs":[
945 | {
946 | "indexed":false,
947 | "name":"redeemer",
948 | "type":"address"
949 | },
950 | {
951 | "indexed":false,
952 | "name":"redeemAmount",
953 | "type":"uint256"
954 | },
955 | {
956 | "indexed":false,
957 | "name":"redeemTokens",
958 | "type":"uint256"
959 | }
960 | ],
961 | "name":"Redeem",
962 | "type":"event",
963 | "signature":"0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929"
964 | },
965 | {
966 | "anonymous":false,
967 | "inputs":[
968 | {
969 | "indexed":false,
970 | "name":"borrower",
971 | "type":"address"
972 | },
973 | {
974 | "indexed":false,
975 | "name":"borrowAmount",
976 | "type":"uint256"
977 | },
978 | {
979 | "indexed":false,
980 | "name":"accountBorrows",
981 | "type":"uint256"
982 | },
983 | {
984 | "indexed":false,
985 | "name":"totalBorrows",
986 | "type":"uint256"
987 | }
988 | ],
989 | "name":"Borrow",
990 | "type":"event",
991 | "signature":"0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80"
992 | },
993 | {
994 | "anonymous":false,
995 | "inputs":[
996 | {
997 | "indexed":false,
998 | "name":"payer",
999 | "type":"address"
1000 | },
1001 | {
1002 | "indexed":false,
1003 | "name":"borrower",
1004 | "type":"address"
1005 | },
1006 | {
1007 | "indexed":false,
1008 | "name":"repayAmount",
1009 | "type":"uint256"
1010 | },
1011 | {
1012 | "indexed":false,
1013 | "name":"accountBorrows",
1014 | "type":"uint256"
1015 | },
1016 | {
1017 | "indexed":false,
1018 | "name":"totalBorrows",
1019 | "type":"uint256"
1020 | }
1021 | ],
1022 | "name":"RepayBorrow",
1023 | "type":"event",
1024 | "signature":"0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1"
1025 | },
1026 | {
1027 | "anonymous":false,
1028 | "inputs":[
1029 | {
1030 | "indexed":false,
1031 | "name":"liquidator",
1032 | "type":"address"
1033 | },
1034 | {
1035 | "indexed":false,
1036 | "name":"borrower",
1037 | "type":"address"
1038 | },
1039 | {
1040 | "indexed":false,
1041 | "name":"repayAmount",
1042 | "type":"uint256"
1043 | },
1044 | {
1045 | "indexed":false,
1046 | "name":"cTokenCollateral",
1047 | "type":"address"
1048 | },
1049 | {
1050 | "indexed":false,
1051 | "name":"seizeTokens",
1052 | "type":"uint256"
1053 | }
1054 | ],
1055 | "name":"LiquidateBorrow",
1056 | "type":"event",
1057 | "signature":"0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52"
1058 | },
1059 | {
1060 | "anonymous":false,
1061 | "inputs":[
1062 | {
1063 | "indexed":false,
1064 | "name":"oldPendingAdmin",
1065 | "type":"address"
1066 | },
1067 | {
1068 | "indexed":false,
1069 | "name":"newPendingAdmin",
1070 | "type":"address"
1071 | }
1072 | ],
1073 | "name":"NewPendingAdmin",
1074 | "type":"event",
1075 | "signature":"0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9"
1076 | },
1077 | {
1078 | "anonymous":false,
1079 | "inputs":[
1080 | {
1081 | "indexed":false,
1082 | "name":"oldAdmin",
1083 | "type":"address"
1084 | },
1085 | {
1086 | "indexed":false,
1087 | "name":"newAdmin",
1088 | "type":"address"
1089 | }
1090 | ],
1091 | "name":"NewAdmin",
1092 | "type":"event",
1093 | "signature":"0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc"
1094 | },
1095 | {
1096 | "anonymous":false,
1097 | "inputs":[
1098 | {
1099 | "indexed":false,
1100 | "name":"oldComptroller",
1101 | "type":"address"
1102 | },
1103 | {
1104 | "indexed":false,
1105 | "name":"newComptroller",
1106 | "type":"address"
1107 | }
1108 | ],
1109 | "name":"NewComptroller",
1110 | "type":"event",
1111 | "signature":"0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d"
1112 | },
1113 | {
1114 | "anonymous":false,
1115 | "inputs":[
1116 | {
1117 | "indexed":false,
1118 | "name":"oldInterestRateModel",
1119 | "type":"address"
1120 | },
1121 | {
1122 | "indexed":false,
1123 | "name":"newInterestRateModel",
1124 | "type":"address"
1125 | }
1126 | ],
1127 | "name":"NewMarketInterestRateModel",
1128 | "type":"event",
1129 | "signature":"0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926"
1130 | },
1131 | {
1132 | "anonymous":false,
1133 | "inputs":[
1134 | {
1135 | "indexed":false,
1136 | "name":"oldReserveFactorMantissa",
1137 | "type":"uint256"
1138 | },
1139 | {
1140 | "indexed":false,
1141 | "name":"newReserveFactorMantissa",
1142 | "type":"uint256"
1143 | }
1144 | ],
1145 | "name":"NewReserveFactor",
1146 | "type":"event",
1147 | "signature":"0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460"
1148 | },
1149 | {
1150 | "anonymous":false,
1151 | "inputs":[
1152 | {
1153 | "indexed":false,
1154 | "name":"admin",
1155 | "type":"address"
1156 | },
1157 | {
1158 | "indexed":false,
1159 | "name":"reduceAmount",
1160 | "type":"uint256"
1161 | },
1162 | {
1163 | "indexed":false,
1164 | "name":"newTotalReserves",
1165 | "type":"uint256"
1166 | }
1167 | ],
1168 | "name":"ReservesReduced",
1169 | "type":"event",
1170 | "signature":"0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e"
1171 | },
1172 | {
1173 | "anonymous":false,
1174 | "inputs":[
1175 | {
1176 | "indexed":false,
1177 | "name":"error",
1178 | "type":"uint256"
1179 | },
1180 | {
1181 | "indexed":false,
1182 | "name":"info",
1183 | "type":"uint256"
1184 | },
1185 | {
1186 | "indexed":false,
1187 | "name":"detail",
1188 | "type":"uint256"
1189 | }
1190 | ],
1191 | "name":"Failure",
1192 | "type":"event",
1193 | "signature":"0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0"
1194 | },
1195 | {
1196 | "anonymous":false,
1197 | "inputs":[
1198 | {
1199 | "indexed":true,
1200 | "name":"from",
1201 | "type":"address"
1202 | },
1203 | {
1204 | "indexed":true,
1205 | "name":"to",
1206 | "type":"address"
1207 | },
1208 | {
1209 | "indexed":false,
1210 | "name":"amount",
1211 | "type":"uint256"
1212 | }
1213 | ],
1214 | "name":"Transfer",
1215 | "type":"event",
1216 | "signature":"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
1217 | },
1218 | {
1219 | "anonymous":false,
1220 | "inputs":[
1221 | {
1222 | "indexed":true,
1223 | "name":"owner",
1224 | "type":"address"
1225 | },
1226 | {
1227 | "indexed":true,
1228 | "name":"spender",
1229 | "type":"address"
1230 | },
1231 | {
1232 | "indexed":false,
1233 | "name":"amount",
1234 | "type":"uint256"
1235 | }
1236 | ],
1237 | "name":"Approval",
1238 | "type":"event",
1239 | "signature":"0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"
1240 | }
1241 | ]
--------------------------------------------------------------------------------
/timelock/abi/cToken-abi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "constant":true,
4 | "inputs":[
5 |
6 | ],
7 | "name":"name",
8 | "outputs":[
9 | {
10 | "name":"",
11 | "type":"string"
12 | }
13 | ],
14 | "payable":false,
15 | "stateMutability":"view",
16 | "type":"function",
17 | "signature":"0x06fdde03"
18 | },
19 | {
20 | "constant":false,
21 | "inputs":[
22 | {
23 | "name":"spender",
24 | "type":"address"
25 | },
26 | {
27 | "name":"amount",
28 | "type":"uint256"
29 | }
30 | ],
31 | "name":"approve",
32 | "outputs":[
33 | {
34 | "name":"",
35 | "type":"bool"
36 | }
37 | ],
38 | "payable":false,
39 | "stateMutability":"nonpayable",
40 | "type":"function",
41 | "signature":"0x095ea7b3"
42 | },
43 | {
44 | "constant":false,
45 | "inputs":[
46 | {
47 | "name":"repayAmount",
48 | "type":"uint256"
49 | }
50 | ],
51 | "name":"repayBorrow",
52 | "outputs":[
53 | {
54 | "name":"",
55 | "type":"uint256"
56 | }
57 | ],
58 | "payable":false,
59 | "stateMutability":"nonpayable",
60 | "type":"function",
61 | "signature":"0x0e752702"
62 | },
63 | {
64 | "constant":true,
65 | "inputs":[
66 |
67 | ],
68 | "name":"reserveFactorMantissa",
69 | "outputs":[
70 | {
71 | "name":"",
72 | "type":"uint256"
73 | }
74 | ],
75 | "payable":false,
76 | "stateMutability":"view",
77 | "type":"function",
78 | "signature":"0x173b9904"
79 | },
80 | {
81 | "constant":false,
82 | "inputs":[
83 | {
84 | "name":"account",
85 | "type":"address"
86 | }
87 | ],
88 | "name":"borrowBalanceCurrent",
89 | "outputs":[
90 | {
91 | "name":"",
92 | "type":"uint256"
93 | }
94 | ],
95 | "payable":false,
96 | "stateMutability":"nonpayable",
97 | "type":"function",
98 | "signature":"0x17bfdfbc"
99 | },
100 | {
101 | "constant":true,
102 | "inputs":[
103 |
104 | ],
105 | "name":"totalSupply",
106 | "outputs":[
107 | {
108 | "name":"",
109 | "type":"uint256"
110 | }
111 | ],
112 | "payable":false,
113 | "stateMutability":"view",
114 | "type":"function",
115 | "signature":"0x18160ddd"
116 | },
117 | {
118 | "constant":true,
119 | "inputs":[
120 |
121 | ],
122 | "name":"exchangeRateStored",
123 | "outputs":[
124 | {
125 | "name":"",
126 | "type":"uint256"
127 | }
128 | ],
129 | "payable":false,
130 | "stateMutability":"view",
131 | "type":"function",
132 | "signature":"0x182df0f5"
133 | },
134 | {
135 | "constant":false,
136 | "inputs":[
137 | {
138 | "name":"src",
139 | "type":"address"
140 | },
141 | {
142 | "name":"dst",
143 | "type":"address"
144 | },
145 | {
146 | "name":"amount",
147 | "type":"uint256"
148 | }
149 | ],
150 | "name":"transferFrom",
151 | "outputs":[
152 | {
153 | "name":"",
154 | "type":"bool"
155 | }
156 | ],
157 | "payable":false,
158 | "stateMutability":"nonpayable",
159 | "type":"function",
160 | "signature":"0x23b872dd"
161 | },
162 | {
163 | "constant":false,
164 | "inputs":[
165 | {
166 | "name":"borrower",
167 | "type":"address"
168 | },
169 | {
170 | "name":"repayAmount",
171 | "type":"uint256"
172 | }
173 | ],
174 | "name":"repayBorrowBehalf",
175 | "outputs":[
176 | {
177 | "name":"",
178 | "type":"uint256"
179 | }
180 | ],
181 | "payable":false,
182 | "stateMutability":"nonpayable",
183 | "type":"function",
184 | "signature":"0x2608f818"
185 | },
186 | {
187 | "constant":true,
188 | "inputs":[
189 |
190 | ],
191 | "name":"pendingAdmin",
192 | "outputs":[
193 | {
194 | "name":"",
195 | "type":"address"
196 | }
197 | ],
198 | "payable":false,
199 | "stateMutability":"view",
200 | "type":"function",
201 | "signature":"0x26782247"
202 | },
203 | {
204 | "constant":true,
205 | "inputs":[
206 |
207 | ],
208 | "name":"decimals",
209 | "outputs":[
210 | {
211 | "name":"",
212 | "type":"uint256"
213 | }
214 | ],
215 | "payable":false,
216 | "stateMutability":"view",
217 | "type":"function",
218 | "signature":"0x313ce567"
219 | },
220 | {
221 | "constant":false,
222 | "inputs":[
223 | {
224 | "name":"owner",
225 | "type":"address"
226 | }
227 | ],
228 | "name":"balanceOfUnderlying",
229 | "outputs":[
230 | {
231 | "name":"",
232 | "type":"uint256"
233 | }
234 | ],
235 | "payable":false,
236 | "stateMutability":"nonpayable",
237 | "type":"function",
238 | "signature":"0x3af9e669"
239 | },
240 | {
241 | "constant":true,
242 | "inputs":[
243 |
244 | ],
245 | "name":"getCash",
246 | "outputs":[
247 | {
248 | "name":"",
249 | "type":"uint256"
250 | }
251 | ],
252 | "payable":false,
253 | "stateMutability":"view",
254 | "type":"function",
255 | "signature":"0x3b1d21a2"
256 | },
257 | {
258 | "constant":false,
259 | "inputs":[
260 | {
261 | "name":"newComptroller",
262 | "type":"address"
263 | }
264 | ],
265 | "name":"_setComptroller",
266 | "outputs":[
267 | {
268 | "name":"",
269 | "type":"uint256"
270 | }
271 | ],
272 | "payable":false,
273 | "stateMutability":"nonpayable",
274 | "type":"function",
275 | "signature":"0x4576b5db"
276 | },
277 | {
278 | "constant":true,
279 | "inputs":[
280 |
281 | ],
282 | "name":"totalBorrows",
283 | "outputs":[
284 | {
285 | "name":"",
286 | "type":"uint256"
287 | }
288 | ],
289 | "payable":false,
290 | "stateMutability":"view",
291 | "type":"function",
292 | "signature":"0x47bd3718"
293 | },
294 | {
295 | "constant":true,
296 | "inputs":[
297 |
298 | ],
299 | "name":"comptroller",
300 | "outputs":[
301 | {
302 | "name":"",
303 | "type":"address"
304 | }
305 | ],
306 | "payable":false,
307 | "stateMutability":"view",
308 | "type":"function",
309 | "signature":"0x5fe3b567"
310 | },
311 | {
312 | "constant":false,
313 | "inputs":[
314 | {
315 | "name":"reduceAmount",
316 | "type":"uint256"
317 | }
318 | ],
319 | "name":"_reduceReserves",
320 | "outputs":[
321 | {
322 | "name":"",
323 | "type":"uint256"
324 | }
325 | ],
326 | "payable":false,
327 | "stateMutability":"nonpayable",
328 | "type":"function",
329 | "signature":"0x601a0bf1"
330 | },
331 | {
332 | "constant":true,
333 | "inputs":[
334 |
335 | ],
336 | "name":"initialExchangeRateMantissa",
337 | "outputs":[
338 | {
339 | "name":"",
340 | "type":"uint256"
341 | }
342 | ],
343 | "payable":false,
344 | "stateMutability":"view",
345 | "type":"function",
346 | "signature":"0x675d972c"
347 | },
348 | {
349 | "constant":true,
350 | "inputs":[
351 |
352 | ],
353 | "name":"accrualBlockNumber",
354 | "outputs":[
355 | {
356 | "name":"",
357 | "type":"uint256"
358 | }
359 | ],
360 | "payable":false,
361 | "stateMutability":"view",
362 | "type":"function",
363 | "signature":"0x6c540baf"
364 | },
365 | {
366 | "constant":true,
367 | "inputs":[
368 |
369 | ],
370 | "name":"underlying",
371 | "outputs":[
372 | {
373 | "name":"",
374 | "type":"address"
375 | }
376 | ],
377 | "payable":false,
378 | "stateMutability":"view",
379 | "type":"function",
380 | "signature":"0x6f307dc3"
381 | },
382 | {
383 | "constant":true,
384 | "inputs":[
385 | {
386 | "name":"owner",
387 | "type":"address"
388 | }
389 | ],
390 | "name":"balanceOf",
391 | "outputs":[
392 | {
393 | "name":"",
394 | "type":"uint256"
395 | }
396 | ],
397 | "payable":false,
398 | "stateMutability":"view",
399 | "type":"function",
400 | "signature":"0x70a08231"
401 | },
402 | {
403 | "constant":false,
404 | "inputs":[
405 |
406 | ],
407 | "name":"totalBorrowsCurrent",
408 | "outputs":[
409 | {
410 | "name":"",
411 | "type":"uint256"
412 | }
413 | ],
414 | "payable":false,
415 | "stateMutability":"nonpayable",
416 | "type":"function",
417 | "signature":"0x73acee98"
418 | },
419 | {
420 | "constant":false,
421 | "inputs":[
422 | {
423 | "name":"redeemAmount",
424 | "type":"uint256"
425 | }
426 | ],
427 | "name":"redeemUnderlying",
428 | "outputs":[
429 | {
430 | "name":"",
431 | "type":"uint256"
432 | }
433 | ],
434 | "payable":false,
435 | "stateMutability":"nonpayable",
436 | "type":"function",
437 | "signature":"0x852a12e3"
438 | },
439 | {
440 | "constant":true,
441 | "inputs":[
442 |
443 | ],
444 | "name":"totalReserves",
445 | "outputs":[
446 | {
447 | "name":"",
448 | "type":"uint256"
449 | }
450 | ],
451 | "payable":false,
452 | "stateMutability":"view",
453 | "type":"function",
454 | "signature":"0x8f840ddd"
455 | },
456 | {
457 | "constant":true,
458 | "inputs":[
459 |
460 | ],
461 | "name":"symbol",
462 | "outputs":[
463 | {
464 | "name":"",
465 | "type":"string"
466 | }
467 | ],
468 | "payable":false,
469 | "stateMutability":"view",
470 | "type":"function",
471 | "signature":"0x95d89b41"
472 | },
473 | {
474 | "constant":true,
475 | "inputs":[
476 | {
477 | "name":"account",
478 | "type":"address"
479 | }
480 | ],
481 | "name":"borrowBalanceStored",
482 | "outputs":[
483 | {
484 | "name":"",
485 | "type":"uint256"
486 | }
487 | ],
488 | "payable":false,
489 | "stateMutability":"view",
490 | "type":"function",
491 | "signature":"0x95dd9193"
492 | },
493 | {
494 | "constant":false,
495 | "inputs":[
496 | {
497 | "name":"mintAmount",
498 | "type":"uint256"
499 | }
500 | ],
501 | "name":"mint",
502 | "outputs":[
503 | {
504 | "name":"",
505 | "type":"uint256"
506 | }
507 | ],
508 | "payable":false,
509 | "stateMutability":"nonpayable",
510 | "type":"function",
511 | "signature":"0xa0712d68"
512 | },
513 | {
514 | "constant":false,
515 | "inputs":[
516 |
517 | ],
518 | "name":"accrueInterest",
519 | "outputs":[
520 | {
521 | "name":"",
522 | "type":"uint256"
523 | }
524 | ],
525 | "payable":false,
526 | "stateMutability":"nonpayable",
527 | "type":"function",
528 | "signature":"0xa6afed95"
529 | },
530 | {
531 | "constant":false,
532 | "inputs":[
533 | {
534 | "name":"dst",
535 | "type":"address"
536 | },
537 | {
538 | "name":"amount",
539 | "type":"uint256"
540 | }
541 | ],
542 | "name":"transfer",
543 | "outputs":[
544 | {
545 | "name":"",
546 | "type":"bool"
547 | }
548 | ],
549 | "payable":false,
550 | "stateMutability":"nonpayable",
551 | "type":"function",
552 | "signature":"0xa9059cbb"
553 | },
554 | {
555 | "constant":true,
556 | "inputs":[
557 |
558 | ],
559 | "name":"borrowIndex",
560 | "outputs":[
561 | {
562 | "name":"",
563 | "type":"uint256"
564 | }
565 | ],
566 | "payable":false,
567 | "stateMutability":"view",
568 | "type":"function",
569 | "signature":"0xaa5af0fd"
570 | },
571 | {
572 | "constant":true,
573 | "inputs":[
574 |
575 | ],
576 | "name":"supplyRatePerBlock",
577 | "outputs":[
578 | {
579 | "name":"",
580 | "type":"uint256"
581 | }
582 | ],
583 | "payable":false,
584 | "stateMutability":"view",
585 | "type":"function",
586 | "signature":"0xae9d70b0"
587 | },
588 | {
589 | "constant":false,
590 | "inputs":[
591 | {
592 | "name":"liquidator",
593 | "type":"address"
594 | },
595 | {
596 | "name":"borrower",
597 | "type":"address"
598 | },
599 | {
600 | "name":"seizeTokens",
601 | "type":"uint256"
602 | }
603 | ],
604 | "name":"seize",
605 | "outputs":[
606 | {
607 | "name":"",
608 | "type":"uint256"
609 | }
610 | ],
611 | "payable":false,
612 | "stateMutability":"nonpayable",
613 | "type":"function",
614 | "signature":"0xb2a02ff1"
615 | },
616 | {
617 | "constant":false,
618 | "inputs":[
619 | {
620 | "name":"newPendingAdmin",
621 | "type":"address"
622 | }
623 | ],
624 | "name":"_setPendingAdmin",
625 | "outputs":[
626 | {
627 | "name":"",
628 | "type":"uint256"
629 | }
630 | ],
631 | "payable":false,
632 | "stateMutability":"nonpayable",
633 | "type":"function",
634 | "signature":"0xb71d1a0c"
635 | },
636 | {
637 | "constant":false,
638 | "inputs":[
639 |
640 | ],
641 | "name":"exchangeRateCurrent",
642 | "outputs":[
643 | {
644 | "name":"",
645 | "type":"uint256"
646 | }
647 | ],
648 | "payable":false,
649 | "stateMutability":"nonpayable",
650 | "type":"function",
651 | "signature":"0xbd6d894d"
652 | },
653 | {
654 | "constant":true,
655 | "inputs":[
656 | {
657 | "name":"account",
658 | "type":"address"
659 | }
660 | ],
661 | "name":"getAccountSnapshot",
662 | "outputs":[
663 | {
664 | "name":"",
665 | "type":"uint256"
666 | },
667 | {
668 | "name":"",
669 | "type":"uint256"
670 | },
671 | {
672 | "name":"",
673 | "type":"uint256"
674 | },
675 | {
676 | "name":"",
677 | "type":"uint256"
678 | }
679 | ],
680 | "payable":false,
681 | "stateMutability":"view",
682 | "type":"function",
683 | "signature":"0xc37f68e2"
684 | },
685 | {
686 | "constant":false,
687 | "inputs":[
688 | {
689 | "name":"borrowAmount",
690 | "type":"uint256"
691 | }
692 | ],
693 | "name":"borrow",
694 | "outputs":[
695 | {
696 | "name":"",
697 | "type":"uint256"
698 | }
699 | ],
700 | "payable":false,
701 | "stateMutability":"nonpayable",
702 | "type":"function",
703 | "signature":"0xc5ebeaec"
704 | },
705 | {
706 | "constant":false,
707 | "inputs":[
708 | {
709 | "name":"redeemTokens",
710 | "type":"uint256"
711 | }
712 | ],
713 | "name":"redeem",
714 | "outputs":[
715 | {
716 | "name":"",
717 | "type":"uint256"
718 | }
719 | ],
720 | "payable":false,
721 | "stateMutability":"nonpayable",
722 | "type":"function",
723 | "signature":"0xdb006a75"
724 | },
725 | {
726 | "constant":true,
727 | "inputs":[
728 | {
729 | "name":"owner",
730 | "type":"address"
731 | },
732 | {
733 | "name":"spender",
734 | "type":"address"
735 | }
736 | ],
737 | "name":"allowance",
738 | "outputs":[
739 | {
740 | "name":"",
741 | "type":"uint256"
742 | }
743 | ],
744 | "payable":false,
745 | "stateMutability":"view",
746 | "type":"function",
747 | "signature":"0xdd62ed3e"
748 | },
749 | {
750 | "constant":false,
751 | "inputs":[
752 |
753 | ],
754 | "name":"_acceptAdmin",
755 | "outputs":[
756 | {
757 | "name":"",
758 | "type":"uint256"
759 | }
760 | ],
761 | "payable":false,
762 | "stateMutability":"nonpayable",
763 | "type":"function",
764 | "signature":"0xe9c714f2"
765 | },
766 | {
767 | "constant":false,
768 | "inputs":[
769 | {
770 | "name":"newInterestRateModel",
771 | "type":"address"
772 | }
773 | ],
774 | "name":"_setInterestRateModel",
775 | "outputs":[
776 | {
777 | "name":"",
778 | "type":"uint256"
779 | }
780 | ],
781 | "payable":false,
782 | "stateMutability":"nonpayable",
783 | "type":"function",
784 | "signature":"0xf2b3abbd"
785 | },
786 | {
787 | "constant":true,
788 | "inputs":[
789 |
790 | ],
791 | "name":"interestRateModel",
792 | "outputs":[
793 | {
794 | "name":"",
795 | "type":"address"
796 | }
797 | ],
798 | "payable":false,
799 | "stateMutability":"view",
800 | "type":"function",
801 | "signature":"0xf3fdb15a"
802 | },
803 | {
804 | "constant":false,
805 | "inputs":[
806 | {
807 | "name":"borrower",
808 | "type":"address"
809 | },
810 | {
811 | "name":"repayAmount",
812 | "type":"uint256"
813 | },
814 | {
815 | "name":"cTokenCollateral",
816 | "type":"address"
817 | }
818 | ],
819 | "name":"liquidateBorrow",
820 | "outputs":[
821 | {
822 | "name":"",
823 | "type":"uint256"
824 | }
825 | ],
826 | "payable":false,
827 | "stateMutability":"nonpayable",
828 | "type":"function",
829 | "signature":"0xf5e3c462"
830 | },
831 | {
832 | "constant":true,
833 | "inputs":[
834 |
835 | ],
836 | "name":"admin",
837 | "outputs":[
838 | {
839 | "name":"",
840 | "type":"address"
841 | }
842 | ],
843 | "payable":false,
844 | "stateMutability":"view",
845 | "type":"function",
846 | "signature":"0xf851a440"
847 | },
848 | {
849 | "constant":true,
850 | "inputs":[
851 |
852 | ],
853 | "name":"borrowRatePerBlock",
854 | "outputs":[
855 | {
856 | "name":"",
857 | "type":"uint256"
858 | }
859 | ],
860 | "payable":false,
861 | "stateMutability":"view",
862 | "type":"function",
863 | "signature":"0xf8f9da28"
864 | },
865 | {
866 | "constant":false,
867 | "inputs":[
868 | {
869 | "name":"newReserveFactorMantissa",
870 | "type":"uint256"
871 | }
872 | ],
873 | "name":"_setReserveFactor",
874 | "outputs":[
875 | {
876 | "name":"",
877 | "type":"uint256"
878 | }
879 | ],
880 | "payable":false,
881 | "stateMutability":"nonpayable",
882 | "type":"function",
883 | "signature":"0xfca7820b"
884 | },
885 | {
886 | "constant":true,
887 | "inputs":[
888 |
889 | ],
890 | "name":"isCToken",
891 | "outputs":[
892 | {
893 | "name":"",
894 | "type":"bool"
895 | }
896 | ],
897 | "payable":false,
898 | "stateMutability":"view",
899 | "type":"function",
900 | "signature":"0xfe9c44ae"
901 | },
902 | {
903 | "inputs":[
904 | {
905 | "name":"underlying_",
906 | "type":"address"
907 | },
908 | {
909 | "name":"comptroller_",
910 | "type":"address"
911 | },
912 | {
913 | "name":"interestRateModel_",
914 | "type":"address"
915 | },
916 | {
917 | "name":"initialExchangeRateMantissa_",
918 | "type":"uint256"
919 | },
920 | {
921 | "name":"name_",
922 | "type":"string"
923 | },
924 | {
925 | "name":"symbol_",
926 | "type":"string"
927 | },
928 | {
929 | "name":"decimals_",
930 | "type":"uint256"
931 | }
932 | ],
933 | "payable":false,
934 | "stateMutability":"nonpayable",
935 | "type":"constructor",
936 | "signature":"constructor"
937 | },
938 | {
939 | "anonymous":false,
940 | "inputs":[
941 | {
942 | "indexed":false,
943 | "name":"interestAccumulated",
944 | "type":"uint256"
945 | },
946 | {
947 | "indexed":false,
948 | "name":"borrowIndex",
949 | "type":"uint256"
950 | },
951 | {
952 | "indexed":false,
953 | "name":"totalBorrows",
954 | "type":"uint256"
955 | }
956 | ],
957 | "name":"AccrueInterest",
958 | "type":"event",
959 | "signature":"0x875352fb3fadeb8c0be7cbbe8ff761b308fa7033470cd0287f02f3436fd76cb9"
960 | },
961 | {
962 | "anonymous":false,
963 | "inputs":[
964 | {
965 | "indexed":false,
966 | "name":"minter",
967 | "type":"address"
968 | },
969 | {
970 | "indexed":false,
971 | "name":"mintAmount",
972 | "type":"uint256"
973 | },
974 | {
975 | "indexed":false,
976 | "name":"mintTokens",
977 | "type":"uint256"
978 | }
979 | ],
980 | "name":"Mint",
981 | "type":"event",
982 | "signature":"0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f"
983 | },
984 | {
985 | "anonymous":false,
986 | "inputs":[
987 | {
988 | "indexed":false,
989 | "name":"redeemer",
990 | "type":"address"
991 | },
992 | {
993 | "indexed":false,
994 | "name":"redeemAmount",
995 | "type":"uint256"
996 | },
997 | {
998 | "indexed":false,
999 | "name":"redeemTokens",
1000 | "type":"uint256"
1001 | }
1002 | ],
1003 | "name":"Redeem",
1004 | "type":"event",
1005 | "signature":"0xe5b754fb1abb7f01b499791d0b820ae3b6af3424ac1c59768edb53f4ec31a929"
1006 | },
1007 | {
1008 | "anonymous":false,
1009 | "inputs":[
1010 | {
1011 | "indexed":false,
1012 | "name":"borrower",
1013 | "type":"address"
1014 | },
1015 | {
1016 | "indexed":false,
1017 | "name":"borrowAmount",
1018 | "type":"uint256"
1019 | },
1020 | {
1021 | "indexed":false,
1022 | "name":"accountBorrows",
1023 | "type":"uint256"
1024 | },
1025 | {
1026 | "indexed":false,
1027 | "name":"totalBorrows",
1028 | "type":"uint256"
1029 | }
1030 | ],
1031 | "name":"Borrow",
1032 | "type":"event",
1033 | "signature":"0x13ed6866d4e1ee6da46f845c46d7e54120883d75c5ea9a2dacc1c4ca8984ab80"
1034 | },
1035 | {
1036 | "anonymous":false,
1037 | "inputs":[
1038 | {
1039 | "indexed":false,
1040 | "name":"payer",
1041 | "type":"address"
1042 | },
1043 | {
1044 | "indexed":false,
1045 | "name":"borrower",
1046 | "type":"address"
1047 | },
1048 | {
1049 | "indexed":false,
1050 | "name":"repayAmount",
1051 | "type":"uint256"
1052 | },
1053 | {
1054 | "indexed":false,
1055 | "name":"accountBorrows",
1056 | "type":"uint256"
1057 | },
1058 | {
1059 | "indexed":false,
1060 | "name":"totalBorrows",
1061 | "type":"uint256"
1062 | }
1063 | ],
1064 | "name":"RepayBorrow",
1065 | "type":"event",
1066 | "signature":"0x1a2a22cb034d26d1854bdc6666a5b91fe25efbbb5dcad3b0355478d6f5c362a1"
1067 | },
1068 | {
1069 | "anonymous":false,
1070 | "inputs":[
1071 | {
1072 | "indexed":false,
1073 | "name":"liquidator",
1074 | "type":"address"
1075 | },
1076 | {
1077 | "indexed":false,
1078 | "name":"borrower",
1079 | "type":"address"
1080 | },
1081 | {
1082 | "indexed":false,
1083 | "name":"repayAmount",
1084 | "type":"uint256"
1085 | },
1086 | {
1087 | "indexed":false,
1088 | "name":"cTokenCollateral",
1089 | "type":"address"
1090 | },
1091 | {
1092 | "indexed":false,
1093 | "name":"seizeTokens",
1094 | "type":"uint256"
1095 | }
1096 | ],
1097 | "name":"LiquidateBorrow",
1098 | "type":"event",
1099 | "signature":"0x298637f684da70674f26509b10f07ec2fbc77a335ab1e7d6215a4b2484d8bb52"
1100 | },
1101 | {
1102 | "anonymous":false,
1103 | "inputs":[
1104 | {
1105 | "indexed":false,
1106 | "name":"oldPendingAdmin",
1107 | "type":"address"
1108 | },
1109 | {
1110 | "indexed":false,
1111 | "name":"newPendingAdmin",
1112 | "type":"address"
1113 | }
1114 | ],
1115 | "name":"NewPendingAdmin",
1116 | "type":"event",
1117 | "signature":"0xca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9"
1118 | },
1119 | {
1120 | "anonymous":false,
1121 | "inputs":[
1122 | {
1123 | "indexed":false,
1124 | "name":"oldAdmin",
1125 | "type":"address"
1126 | },
1127 | {
1128 | "indexed":false,
1129 | "name":"newAdmin",
1130 | "type":"address"
1131 | }
1132 | ],
1133 | "name":"NewAdmin",
1134 | "type":"event",
1135 | "signature":"0xf9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc"
1136 | },
1137 | {
1138 | "anonymous":false,
1139 | "inputs":[
1140 | {
1141 | "indexed":false,
1142 | "name":"oldComptroller",
1143 | "type":"address"
1144 | },
1145 | {
1146 | "indexed":false,
1147 | "name":"newComptroller",
1148 | "type":"address"
1149 | }
1150 | ],
1151 | "name":"NewComptroller",
1152 | "type":"event",
1153 | "signature":"0x7ac369dbd14fa5ea3f473ed67cc9d598964a77501540ba6751eb0b3decf5870d"
1154 | },
1155 | {
1156 | "anonymous":false,
1157 | "inputs":[
1158 | {
1159 | "indexed":false,
1160 | "name":"oldInterestRateModel",
1161 | "type":"address"
1162 | },
1163 | {
1164 | "indexed":false,
1165 | "name":"newInterestRateModel",
1166 | "type":"address"
1167 | }
1168 | ],
1169 | "name":"NewMarketInterestRateModel",
1170 | "type":"event",
1171 | "signature":"0xedffc32e068c7c95dfd4bdfd5c4d939a084d6b11c4199eac8436ed234d72f926"
1172 | },
1173 | {
1174 | "anonymous":false,
1175 | "inputs":[
1176 | {
1177 | "indexed":false,
1178 | "name":"oldReserveFactorMantissa",
1179 | "type":"uint256"
1180 | },
1181 | {
1182 | "indexed":false,
1183 | "name":"newReserveFactorMantissa",
1184 | "type":"uint256"
1185 | }
1186 | ],
1187 | "name":"NewReserveFactor",
1188 | "type":"event",
1189 | "signature":"0xaaa68312e2ea9d50e16af5068410ab56e1a1fd06037b1a35664812c30f821460"
1190 | },
1191 | {
1192 | "anonymous":false,
1193 | "inputs":[
1194 | {
1195 | "indexed":false,
1196 | "name":"admin",
1197 | "type":"address"
1198 | },
1199 | {
1200 | "indexed":false,
1201 | "name":"reduceAmount",
1202 | "type":"uint256"
1203 | },
1204 | {
1205 | "indexed":false,
1206 | "name":"newTotalReserves",
1207 | "type":"uint256"
1208 | }
1209 | ],
1210 | "name":"ReservesReduced",
1211 | "type":"event",
1212 | "signature":"0x3bad0c59cf2f06e7314077049f48a93578cd16f5ef92329f1dab1420a99c177e"
1213 | },
1214 | {
1215 | "anonymous":false,
1216 | "inputs":[
1217 | {
1218 | "indexed":false,
1219 | "name":"error",
1220 | "type":"uint256"
1221 | },
1222 | {
1223 | "indexed":false,
1224 | "name":"info",
1225 | "type":"uint256"
1226 | },
1227 | {
1228 | "indexed":false,
1229 | "name":"detail",
1230 | "type":"uint256"
1231 | }
1232 | ],
1233 | "name":"Failure",
1234 | "type":"event",
1235 | "signature":"0x45b96fe442630264581b197e84bbada861235052c5a1aadfff9ea4e40a969aa0"
1236 | },
1237 | {
1238 | "anonymous":false,
1239 | "inputs":[
1240 | {
1241 | "indexed":true,
1242 | "name":"from",
1243 | "type":"address"
1244 | },
1245 | {
1246 | "indexed":true,
1247 | "name":"to",
1248 | "type":"address"
1249 | },
1250 | {
1251 | "indexed":false,
1252 | "name":"amount",
1253 | "type":"uint256"
1254 | }
1255 | ],
1256 | "name":"Transfer",
1257 | "type":"event",
1258 | "signature":"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
1259 | },
1260 | {
1261 | "anonymous":false,
1262 | "inputs":[
1263 | {
1264 | "indexed":true,
1265 | "name":"owner",
1266 | "type":"address"
1267 | },
1268 | {
1269 | "indexed":true,
1270 | "name":"spender",
1271 | "type":"address"
1272 | },
1273 | {
1274 | "indexed":false,
1275 | "name":"amount",
1276 | "type":"uint256"
1277 | }
1278 | ],
1279 | "name":"Approval",
1280 | "type":"event",
1281 | "signature":"0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"
1282 | }
1283 | ]
--------------------------------------------------------------------------------
/timelock/abi/timelock-abi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [
4 | { "internalType": "address", "name": "admin_", "type": "address" },
5 | { "internalType": "uint256", "name": "delay_", "type": "uint256" }
6 | ],
7 | "stateMutability": "nonpayable",
8 | "type": "constructor"
9 | },
10 | {
11 | "anonymous": false,
12 | "inputs": [
13 | {
14 | "indexed": true,
15 | "internalType": "bytes32",
16 | "name": "txHash",
17 | "type": "bytes32"
18 | },
19 | {
20 | "indexed": true,
21 | "internalType": "address",
22 | "name": "target",
23 | "type": "address"
24 | },
25 | {
26 | "indexed": false,
27 | "internalType": "uint256",
28 | "name": "value",
29 | "type": "uint256"
30 | },
31 | {
32 | "indexed": false,
33 | "internalType": "string",
34 | "name": "signature",
35 | "type": "string"
36 | },
37 | {
38 | "indexed": false,
39 | "internalType": "bytes",
40 | "name": "data",
41 | "type": "bytes"
42 | },
43 | {
44 | "indexed": false,
45 | "internalType": "uint256",
46 | "name": "eta",
47 | "type": "uint256"
48 | }
49 | ],
50 | "name": "CancelTransaction",
51 | "type": "event"
52 | },
53 | {
54 | "anonymous": false,
55 | "inputs": [
56 | {
57 | "indexed": true,
58 | "internalType": "bytes32",
59 | "name": "txHash",
60 | "type": "bytes32"
61 | },
62 | {
63 | "indexed": true,
64 | "internalType": "address",
65 | "name": "target",
66 | "type": "address"
67 | },
68 | {
69 | "indexed": false,
70 | "internalType": "uint256",
71 | "name": "value",
72 | "type": "uint256"
73 | },
74 | {
75 | "indexed": false,
76 | "internalType": "string",
77 | "name": "signature",
78 | "type": "string"
79 | },
80 | {
81 | "indexed": false,
82 | "internalType": "bytes",
83 | "name": "data",
84 | "type": "bytes"
85 | },
86 | {
87 | "indexed": false,
88 | "internalType": "uint256",
89 | "name": "eta",
90 | "type": "uint256"
91 | }
92 | ],
93 | "name": "ExecuteTransaction",
94 | "type": "event"
95 | },
96 | {
97 | "anonymous": false,
98 | "inputs": [
99 | {
100 | "indexed": true,
101 | "internalType": "address",
102 | "name": "newAdmin",
103 | "type": "address"
104 | }
105 | ],
106 | "name": "NewAdmin",
107 | "type": "event"
108 | },
109 | {
110 | "anonymous": false,
111 | "inputs": [
112 | {
113 | "indexed": true,
114 | "internalType": "uint256",
115 | "name": "newDelay",
116 | "type": "uint256"
117 | }
118 | ],
119 | "name": "NewDelay",
120 | "type": "event"
121 | },
122 | {
123 | "anonymous": false,
124 | "inputs": [
125 | {
126 | "indexed": true,
127 | "internalType": "address",
128 | "name": "newPendingAdmin",
129 | "type": "address"
130 | }
131 | ],
132 | "name": "NewPendingAdmin",
133 | "type": "event"
134 | },
135 | {
136 | "anonymous": false,
137 | "inputs": [
138 | {
139 | "indexed": true,
140 | "internalType": "bytes32",
141 | "name": "txHash",
142 | "type": "bytes32"
143 | },
144 | {
145 | "indexed": true,
146 | "internalType": "address",
147 | "name": "target",
148 | "type": "address"
149 | },
150 | {
151 | "indexed": false,
152 | "internalType": "uint256",
153 | "name": "value",
154 | "type": "uint256"
155 | },
156 | {
157 | "indexed": false,
158 | "internalType": "string",
159 | "name": "signature",
160 | "type": "string"
161 | },
162 | {
163 | "indexed": false,
164 | "internalType": "bytes",
165 | "name": "data",
166 | "type": "bytes"
167 | },
168 | {
169 | "indexed": false,
170 | "internalType": "uint256",
171 | "name": "eta",
172 | "type": "uint256"
173 | }
174 | ],
175 | "name": "QueueTransaction",
176 | "type": "event"
177 | },
178 | {
179 | "inputs": [],
180 | "name": "GRACE_PERIOD",
181 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
182 | "stateMutability": "view",
183 | "type": "function"
184 | },
185 | {
186 | "inputs": [],
187 | "name": "MAXIMUM_DELAY",
188 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
189 | "stateMutability": "view",
190 | "type": "function"
191 | },
192 | {
193 | "inputs": [],
194 | "name": "MINIMUM_DELAY",
195 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
196 | "stateMutability": "view",
197 | "type": "function"
198 | },
199 | {
200 | "inputs": [],
201 | "name": "acceptAdmin",
202 | "outputs": [],
203 | "stateMutability": "nonpayable",
204 | "type": "function"
205 | },
206 | {
207 | "inputs": [],
208 | "name": "admin",
209 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
210 | "stateMutability": "view",
211 | "type": "function"
212 | },
213 | {
214 | "inputs": [],
215 | "name": "admin_initialized",
216 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
217 | "stateMutability": "view",
218 | "type": "function"
219 | },
220 | {
221 | "inputs": [
222 | { "internalType": "address", "name": "target", "type": "address" },
223 | { "internalType": "uint256", "name": "value", "type": "uint256" },
224 | { "internalType": "string", "name": "signature", "type": "string" },
225 | { "internalType": "bytes", "name": "data", "type": "bytes" },
226 | { "internalType": "uint256", "name": "eta", "type": "uint256" }
227 | ],
228 | "name": "cancelTransaction",
229 | "outputs": [],
230 | "stateMutability": "nonpayable",
231 | "type": "function"
232 | },
233 | {
234 | "inputs": [],
235 | "name": "delay",
236 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
237 | "stateMutability": "view",
238 | "type": "function"
239 | },
240 | {
241 | "inputs": [
242 | { "internalType": "address", "name": "target", "type": "address" },
243 | { "internalType": "uint256", "name": "value", "type": "uint256" },
244 | { "internalType": "string", "name": "signature", "type": "string" },
245 | { "internalType": "bytes", "name": "data", "type": "bytes" },
246 | { "internalType": "uint256", "name": "eta", "type": "uint256" }
247 | ],
248 | "name": "executeTransaction",
249 | "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],
250 | "stateMutability": "payable",
251 | "type": "function"
252 | },
253 | {
254 | "inputs": [],
255 | "name": "pendingAdmin",
256 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
257 | "stateMutability": "view",
258 | "type": "function"
259 | },
260 | {
261 | "inputs": [
262 | { "internalType": "address", "name": "target", "type": "address" },
263 | { "internalType": "uint256", "name": "value", "type": "uint256" },
264 | { "internalType": "string", "name": "signature", "type": "string" },
265 | { "internalType": "bytes", "name": "data", "type": "bytes" },
266 | { "internalType": "uint256", "name": "eta", "type": "uint256" }
267 | ],
268 | "name": "queueTransaction",
269 | "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
270 | "stateMutability": "nonpayable",
271 | "type": "function"
272 | },
273 | {
274 | "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }],
275 | "name": "queuedTransactions",
276 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
277 | "stateMutability": "view",
278 | "type": "function"
279 | },
280 | {
281 | "inputs": [
282 | { "internalType": "uint256", "name": "delay_", "type": "uint256" }
283 | ],
284 | "name": "setDelay",
285 | "outputs": [],
286 | "stateMutability": "nonpayable",
287 | "type": "function"
288 | },
289 | {
290 | "inputs": [
291 | { "internalType": "address", "name": "pendingAdmin_", "type": "address" }
292 | ],
293 | "name": "setPendingAdmin",
294 | "outputs": [],
295 | "stateMutability": "nonpayable",
296 | "type": "function"
297 | },
298 | { "stateMutability": "payable", "type": "receive" }
299 | ]
300 |
--------------------------------------------------------------------------------
/timelock/abi/unitroller-abi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs":[
4 |
5 | ],
6 | "payable":false,
7 | "stateMutability":"nonpayable",
8 | "type":"constructor"
9 | },
10 | {
11 | "anonymous":false,
12 | "inputs":[
13 | {
14 | "indexed":false,
15 | "internalType":"uint256",
16 | "name":"error",
17 | "type":"uint256"
18 | },
19 | {
20 | "indexed":false,
21 | "internalType":"uint256",
22 | "name":"info",
23 | "type":"uint256"
24 | },
25 | {
26 | "indexed":false,
27 | "internalType":"uint256",
28 | "name":"detail",
29 | "type":"uint256"
30 | }
31 | ],
32 | "name":"Failure",
33 | "type":"event"
34 | },
35 | {
36 | "anonymous":false,
37 | "inputs":[
38 | {
39 | "indexed":false,
40 | "internalType":"address",
41 | "name":"oldAdmin",
42 | "type":"address"
43 | },
44 | {
45 | "indexed":false,
46 | "internalType":"address",
47 | "name":"newAdmin",
48 | "type":"address"
49 | }
50 | ],
51 | "name":"NewAdmin",
52 | "type":"event"
53 | },
54 | {
55 | "anonymous":false,
56 | "inputs":[
57 | {
58 | "indexed":false,
59 | "internalType":"address",
60 | "name":"oldImplementation",
61 | "type":"address"
62 | },
63 | {
64 | "indexed":false,
65 | "internalType":"address",
66 | "name":"newImplementation",
67 | "type":"address"
68 | }
69 | ],
70 | "name":"NewImplementation",
71 | "type":"event"
72 | },
73 | {
74 | "anonymous":false,
75 | "inputs":[
76 | {
77 | "indexed":false,
78 | "internalType":"address",
79 | "name":"oldPendingAdmin",
80 | "type":"address"
81 | },
82 | {
83 | "indexed":false,
84 | "internalType":"address",
85 | "name":"newPendingAdmin",
86 | "type":"address"
87 | }
88 | ],
89 | "name":"NewPendingAdmin",
90 | "type":"event"
91 | },
92 | {
93 | "anonymous":false,
94 | "inputs":[
95 | {
96 | "indexed":false,
97 | "internalType":"address",
98 | "name":"oldPendingImplementation",
99 | "type":"address"
100 | },
101 | {
102 | "indexed":false,
103 | "internalType":"address",
104 | "name":"newPendingImplementation",
105 | "type":"address"
106 | }
107 | ],
108 | "name":"NewPendingImplementation",
109 | "type":"event"
110 | },
111 | {
112 | "payable":true,
113 | "stateMutability":"payable",
114 | "type":"fallback"
115 | },
116 | {
117 | "constant":false,
118 | "inputs":[
119 |
120 | ],
121 | "name":"_acceptAdmin",
122 | "outputs":[
123 | {
124 | "internalType":"uint256",
125 | "name":"",
126 | "type":"uint256"
127 | }
128 | ],
129 | "payable":false,
130 | "stateMutability":"nonpayable",
131 | "type":"function"
132 | },
133 | {
134 | "constant":false,
135 | "inputs":[
136 |
137 | ],
138 | "name":"_acceptImplementation",
139 | "outputs":[
140 | {
141 | "internalType":"uint256",
142 | "name":"",
143 | "type":"uint256"
144 | }
145 | ],
146 | "payable":false,
147 | "stateMutability":"nonpayable",
148 | "type":"function"
149 | },
150 | {
151 | "constant":false,
152 | "inputs":[
153 | {
154 | "internalType":"address",
155 | "name":"newPendingAdmin",
156 | "type":"address"
157 | }
158 | ],
159 | "name":"_setPendingAdmin",
160 | "outputs":[
161 | {
162 | "internalType":"uint256",
163 | "name":"",
164 | "type":"uint256"
165 | }
166 | ],
167 | "payable":false,
168 | "stateMutability":"nonpayable",
169 | "type":"function"
170 | },
171 | {
172 | "constant":false,
173 | "inputs":[
174 | {
175 | "internalType":"address",
176 | "name":"newPendingImplementation",
177 | "type":"address"
178 | }
179 | ],
180 | "name":"_setPendingImplementation",
181 | "outputs":[
182 | {
183 | "internalType":"uint256",
184 | "name":"",
185 | "type":"uint256"
186 | }
187 | ],
188 | "payable":false,
189 | "stateMutability":"nonpayable",
190 | "type":"function"
191 | },
192 | {
193 | "constant":true,
194 | "inputs":[
195 |
196 | ],
197 | "name":"admin",
198 | "outputs":[
199 | {
200 | "internalType":"address",
201 | "name":"",
202 | "type":"address"
203 | }
204 | ],
205 | "payable":false,
206 | "stateMutability":"view",
207 | "type":"function"
208 | },
209 | {
210 | "constant":true,
211 | "inputs":[
212 |
213 | ],
214 | "name":"comptrollerImplementation",
215 | "outputs":[
216 | {
217 | "internalType":"address",
218 | "name":"",
219 | "type":"address"
220 | }
221 | ],
222 | "payable":false,
223 | "stateMutability":"view",
224 | "type":"function"
225 | },
226 | {
227 | "constant":true,
228 | "inputs":[
229 |
230 | ],
231 | "name":"pendingAdmin",
232 | "outputs":[
233 | {
234 | "internalType":"address",
235 | "name":"",
236 | "type":"address"
237 | }
238 | ],
239 | "payable":false,
240 | "stateMutability":"view",
241 | "type":"function"
242 | },
243 | {
244 | "constant":true,
245 | "inputs":[
246 |
247 | ],
248 | "name":"pendingComptrollerImplementation",
249 | "outputs":[
250 | {
251 | "internalType":"address",
252 | "name":"",
253 | "type":"address"
254 | }
255 | ],
256 | "payable":false,
257 | "stateMutability":"view",
258 | "type":"function"
259 | }
260 | ]
--------------------------------------------------------------------------------
/timelock/constants.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * timelock contract address
3 | */
4 | export const contract_address : any = {
5 | 3: {
6 | 'unitroller': '0x52Ab60E7F463B73C6A90ee116dBB18ac61DC63FF',
7 | 'comptroller': '0x52Ab60E7F463B73C6A90ee116dBB18ac61DC63FF',
8 | 'cToken1': '',
9 | 'cToken2': '',
10 | 'cTokenn': ''
11 | },
12 | 1: {
13 | 'unitroller': '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B',
14 | 'comptroller': '0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B',
15 | 'cToken1': '',
16 | 'cToken2': '',
17 | 'cTokenn': ''
18 | }
19 | }
20 |
21 | /**
22 | * contract abi file name
23 | */
24 | export const contract_abi_file : any = {
25 | 'unitroller': 'unitroller-abi.json',
26 | 'comptroller': 'comptroller-abi.json',
27 | 'cToken1': 'cToken-abi.json',
28 | 'cToken2': 'cToken-abi.json',
29 | 'cTokenn': 'cToken-abi.json'
30 | }
31 |
32 | /**
33 | * deplay Offset, unit: seconds
34 | */
35 | export const delay_offset = 300;
36 |
37 | /**
38 | * Current timelock address
39 | */
40 | export const timelock_address : any = {
41 | 1: '0x6d903f6003cca6255D85CcA4D3B5E5146dC33925',
42 | 3: '0x4168FE8179C5e99074068244413909F40c4301B2'
43 | }
44 |
45 | /**
46 | * contract timelock queue transaction functions
47 | */
48 | export const queue_functions : any = {
49 | 'unitroller': ['_acceptAdmin', '_setPendingAdmin', '_setPendingImplementation'],
50 | 'comptroller': ['_become', '_setBorrowPaused', '_setMiningBuff', '_setCompRate', '_setMintPaused', '_supportMarket', '_dropCompMarket', '_setPriceOracle', '_setCollateralFactor'],
51 | 'cToken1': ['_acceptAdmin', '_setReserveFactor'],
52 | 'cToken2': ['_acceptAdmin', '_setReserveFactor'],
53 | 'cTokenn': ['_acceptAdmin', '_setReserveFactor']
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/timelock/contracts.ts:
--------------------------------------------------------------------------------
1 | import { contract_address, queue_functions, contract_abi_file } from './constants';
2 | import { IABIFunction, ITokenContract } from './interface';
3 |
4 | class Contracts {
5 | private contractsObject: any;
6 | constructor(chainId: number) {
7 | if(!contract_address.hasOwnProperty(chainId)) {
8 | throw new Error(`Don\'t support the current network ${chainId}`);
9 | }
10 | this.contractsObject = contract_address[chainId];
11 | }
12 |
13 | private parseSignature(abiFunc: any) {
14 | let inputType : Array = [];
15 | for(let i = 0; i < abiFunc.inputs.length; i++) {
16 | inputType.push(abiFunc.inputs[i].type);
17 | }
18 |
19 | return `${abiFunc.name}(${inputType.join(',')})`;
20 | }
21 |
22 | private parseFunctions(abi: any, functions: Array) {
23 | let parsedFunctions : Array = [];
24 | for(let i = 0; i < functions.length; i++) {
25 |
26 | let abiFunctionObjList : Array = abi.filter((abiItem: any) => {
27 | return functions[i] == abiItem.name && 'function' == abiItem.type;
28 | });
29 |
30 | if(abiFunctionObjList.length > 0) {
31 | const abiFunctionObj : any = abiFunctionObjList[0];
32 | let abiFunction: IABIFunction = {
33 | name: abiFunctionObj.name,
34 | inputs: abiFunctionObj.inputs,
35 | signature: this.parseSignature(abiFunctionObj),
36 |
37 | abi: abiFunctionObj,
38 | inputValue: ''
39 | };
40 |
41 | parsedFunctions.push(abiFunction);
42 | }
43 | }
44 |
45 | return parsedFunctions;
46 | }
47 |
48 | get timelockContracs() : Array {
49 | let res : Array = [];
50 | for(let key in this.contractsObject) {
51 | let tokenContract : ITokenContract = {
52 | name: key,
53 | address: this.contractsObject[key]
54 | }
55 | const abiFileName : string = contract_abi_file[key];
56 | const abi = require(`~/timelock/abi/${abiFileName}`);
57 | const functions : Array = queue_functions[key];
58 | tokenContract.functions = this.parseFunctions(abi, functions);
59 |
60 | res.push(tokenContract);
61 | }
62 | return res;
63 | }
64 | }
65 |
66 | export default Contracts;
--------------------------------------------------------------------------------
/timelock/dataStorage.ts:
--------------------------------------------------------------------------------
1 | import { ITokenContract } from './interface';
2 |
3 | class DataStorage {
4 | constructor() {
5 |
6 | }
7 |
8 | get tempTokenContract() : ITokenContract | null {
9 | const strTokenContract : string | null = window.localStorage.getItem('temp_token_contract');
10 | if(strTokenContract) {
11 | try{
12 | let res : ITokenContract = {};
13 | const data : any = JSON.parse(strTokenContract);
14 | res = {...data};
15 |
16 | return res;
17 | }
18 | catch(e) {
19 | return null;
20 | }
21 | }
22 |
23 | return null;
24 | }
25 |
26 | set tempTokenContract(value : ITokenContract | null) {
27 | if(null == value) {
28 | window.localStorage.removeItem('temp_token_contract');
29 | }
30 | else {
31 | window.localStorage.setItem('temp_token_contract', JSON.stringify(value));
32 | }
33 | }
34 | }
35 |
36 | export default DataStorage;
--------------------------------------------------------------------------------
/timelock/error.ts:
--------------------------------------------------------------------------------
1 | class ErrorHelper {
2 | static parse(error: any) {
3 | if('object' == typeof error) {
4 | if(error.hasOwnProperty('error')) {
5 | if(error.error.hasOwnProperty('reason')) {
6 | return error.error.reason;
7 | }
8 | else {
9 | return error.error.message;
10 | }
11 | }
12 | else {
13 | if(error.hasOwnProperty('message')){
14 | error = error.message;
15 | if(error.indexOf('(') > -1) {
16 | error = error.substr(0, error.indexOf('('));
17 | }
18 | return error;
19 | }
20 | else {
21 | if(error.indexOf('(') > -1) {
22 | error = error.substr(error.indexOf('('));
23 | }
24 | return error;
25 | }
26 | }
27 | }
28 | else {
29 | return error;
30 | }
31 | }
32 | }
33 |
34 | export default ErrorHelper;
--------------------------------------------------------------------------------
/timelock/interface.ts:
--------------------------------------------------------------------------------
1 | export interface IABIFunction {
2 | signature?: string;
3 | name?: string;
4 | inputs?: Array;
5 | abi?: any;
6 | inputValue?: any;
7 | }
8 |
9 | export interface ITokenContract {
10 | name?: string;
11 | address?: string;
12 | functions?: Array;
13 | }
14 |
15 | export interface ITimelockTransaction {
16 | data?:string;
17 | txData?: string;
18 | txDataHash?: string;
19 | funcData?: string;
20 | from?: string;
21 | blockNumber?: number;
22 | timestamp?: any;
23 | hash?: string;
24 | decodedFunction?: any;
25 | isQueued?: any;
26 | targetInfo?: any;
27 | executeOrCancelTransaction?: ITimelockTransaction;
28 | }
--------------------------------------------------------------------------------
/timelock/provider.ts:
--------------------------------------------------------------------------------
1 | import { accountsChanged, chainChanged } from '~/timelock/wallet'
2 | import BigNumber from 'bignumber.js';
3 |
4 | declare var ethereum: any;
5 |
6 | class EthereumProvider {
7 | constructor() {
8 | if(ethereum && ethereum.isMetaMask) {
9 | console.log('ethereum provider init...');
10 | }
11 | else {
12 | throw new Error('Don\'t support then current ethereum wallet.');
13 | }
14 | }
15 |
16 | async connect(): Promise {
17 | const accounts = await ethereum.request({
18 | method: 'eth_requestAccounts',
19 | });
20 | return accounts.length > 0 ? accounts[0] : null;
21 | }
22 |
23 | monitor(options: any) {
24 | accountsChanged((account: string | null) => {
25 | if ('function' == typeof options.accountChanged) {
26 | options.accountChanged(account)
27 | }
28 | })
29 | chainChanged((chainId: string | number) => {
30 | chainId = new BigNumber(chainId).toNumber()
31 | if ('function' == typeof options.chainChanged) {
32 | options.chainChanged(chainId)
33 | }
34 | })
35 | }
36 |
37 | get provider() : any {
38 | return ethereum;
39 | }
40 |
41 | get chainId() : number {
42 | const res : any = new BigNumber(ethereum.chainId);
43 | return res.toNumber();
44 | }
45 | }
46 |
47 | export default EthereumProvider;
--------------------------------------------------------------------------------
/timelock/timelock.ts:
--------------------------------------------------------------------------------
1 | import EthereumProvider from './provider';
2 | import ethers from 'ethers';
3 | import timelockAbi from './abi/timelock-abi.json';
4 | import { ITimelockTransaction } from './interface';
5 | import { timelock_address, contract_address, contract_abi_file} from './constants'
6 |
7 | const abiDecoder = require('abi-decoder')
8 |
9 | abiDecoder.addABI(timelockAbi);
10 |
11 | function useAbiDecoder() {
12 | let contractFileNameList : Array = [];
13 | for(let key in contract_abi_file) {
14 | contractFileNameList.push(contract_abi_file[key]);
15 | }
16 |
17 | contractFileNameList = Array.from(new Set(contractFileNameList));
18 | for(let i = 0;i < contractFileNameList.length; i++ ) {
19 | const abiFileName : string = contractFileNameList[i];
20 | const abi = require(`~/timelock/abi/${abiFileName}`);
21 | abiDecoder.addABI(abi);
22 | }
23 | }
24 |
25 | useAbiDecoder();
26 |
27 | const specialFunctionNames = [
28 | "queueTransaction",
29 | "cancelTransaction",
30 | "executeTransaction",
31 | ];
32 |
33 | class TimelockHelper {
34 | private ethereumProvider: EthereumProvider;
35 | private account: string | null = '';
36 | private address: string = '';
37 | private contractAddress: any = {};
38 |
39 | constructor(ethereumProvider: EthereumProvider) {
40 | this.ethereumProvider = ethereumProvider;
41 | this.setAddress()
42 | }
43 |
44 | async connect() {
45 | this.account = await this.ethereumProvider.connect();
46 | return this.account;
47 | }
48 |
49 | setAddress() {
50 | this.address = timelock_address[this.ethereumProvider.chainId];
51 | this.contractAddress = contract_address[this.ethereumProvider.chainId];
52 | }
53 |
54 | private trx(method: string, params: Array) {
55 | return new Promise(async (resolve, reject) => {
56 | const provider = new ethers.providers.Web3Provider(this.ethereumProvider.provider).getSigner();
57 | const contract = new ethers.Contract(this.address, timelockAbi, provider);
58 |
59 | contract[method].apply(null, params).then((result : any) => {
60 | resolve(result);
61 | }).catch((error: any) => {
62 | reject({
63 | message: 'Error occurred during [eth_sendTransaction]. See {error}.',
64 | error,
65 | method,
66 | params,
67 | });
68 | });
69 | });
70 | }
71 |
72 | private qrx(method: string, params: Array) {
73 | return new Promise(async (resolve, reject) => {
74 | const provider = new ethers.providers.Web3Provider(this.ethereumProvider.provider).getSigner();
75 | const contract = new ethers.Contract(this.address, timelockAbi, provider);
76 |
77 | contract.callStatic[method].apply(null, params).then((result) => {
78 | resolve(result);
79 | }).catch((error) => {
80 | reject({
81 | message: 'Error occurred during [eth_call]. See {error}.',
82 | error,
83 | method,
84 | params,
85 | });
86 | });
87 |
88 | });
89 | }
90 |
91 | async queueTransaction(params: Array) {
92 | return await this.trx('queueTransaction', params);
93 | }
94 |
95 | async executeTransaction(params: Array) {
96 | return await this.trx('executeTransaction', params);
97 | }
98 |
99 | async cancelTransaction(params: Array) {
100 | return await this.trx('cancelTransaction', params);
101 | }
102 |
103 | abiEncode(types: Array, params: Array) {
104 | return ethers.utils.defaultAbiCoder.encode(types, params);
105 | }
106 |
107 | async getDelay() : Promise {
108 | const delay : any = await this.qrx('delay', []);
109 | return delay.toNumber();
110 | }
111 |
112 | async getTimestamp() : Promise {
113 | const provider = new ethers.providers.Web3Provider(this.ethereumProvider.provider);
114 | const block : any = await provider.getBlock('latest');
115 | return block.timestamp;
116 | }
117 |
118 | async queuedTransactions(txHash: any) {
119 | return await this.qrx('queuedTransactions', [txHash]);
120 | }
121 |
122 | async getHistoryTransactions() {
123 |
124 | var getTargetKey = function(contractAddress: any, target: any) {
125 | let res = '';
126 | for(let key in contractAddress) {
127 | if(contractAddress.hasOwnProperty(key)) {
128 | let value = contractAddress[key].toLowerCase();
129 | if(value == target.toLowerCase()) {
130 | res = key;
131 | break;
132 | }
133 | }
134 | }
135 | return res;
136 | }
137 |
138 | const etherscanProvider = new ethers.providers.EtherscanProvider(this.ethereumProvider.chainId);
139 | const history = await etherscanProvider.getHistory(this.address);
140 | let newest = history.slice(1).reverse();
141 |
142 | const decoded = newest.map(
143 | ({ data, from, blockNumber, timestamp, hash }) => {
144 |
145 | let item: ITimelockTransaction = {data, from, blockNumber, timestamp, hash};
146 | if('undefined' === typeof data || '0x' == data) {
147 | item.txData = '';
148 | item.txDataHash = '';
149 | item.funcData = '0x' ;
150 | item.targetInfo = '';
151 | item.decodedFunction = {};
152 | return item;
153 | }
154 | else {
155 | const decodedFunction = abiDecoder.decodeMethod(data);
156 | if (specialFunctionNames.includes(decodedFunction.name)) {
157 | // target, value, signature, data, eta
158 | try{
159 | const txData = this.abiEncode(['address','uint256','string','bytes','uint256'], [decodedFunction.params[0].value, decodedFunction.params[1].value, decodedFunction.params[2].value, null == decodedFunction.params[3].value ? '0x' : decodedFunction.params[3].value, decodedFunction.params[4].value]);
160 | const txDataHash = ethers.utils.keccak256(txData);
161 |
162 | item.txData = txData;
163 | item.txDataHash = txDataHash;
164 | }
165 | catch(e) {
166 | item.txData = '';
167 | item.txDataHash = '';
168 | }
169 | const funcData = decodedFunction.params[3].value;
170 | item.funcData = null == funcData ? '0x' : funcData;
171 |
172 | if(null !== funcData) {
173 | let decodedData = abiDecoder.decodeMethod(funcData);
174 |
175 | if('undefined' == typeof decodedData) {
176 | const signature = decodedFunction.params[2].value;
177 | const functionParams = signature
178 | .split("(")[1]
179 | .split(")")[0]
180 | .split(",");
181 | decodedData = ethers.utils.defaultAbiCoder.decode(
182 | functionParams,
183 | funcData
184 | );
185 | decodedFunction.params[3].value = decodedData.length == 0 ? [] : "[" + decodedData.map((x : any) => x.toString()).join(", ") + "]";
186 | }
187 | else {
188 | decodedFunction.params[3].value = decodedData.params.map ((_data: any) => {
189 | return _data.value;
190 | });
191 | }
192 |
193 | const target = decodedFunction.params[0].value;
194 | item.targetInfo = getTargetKey(this.contractAddress, target);
195 | }
196 |
197 | item.decodedFunction = decodedFunction;
198 | return item;
199 | }
200 |
201 | }
202 |
203 | return item;
204 | }
205 | );
206 | return decoded;
207 | }
208 |
209 | queuedTransaction(tx: ITimelockTransaction) {
210 | return new Promise(async (resolve) => {
211 | const isTxQueued : any = '' == tx.txDataHash ? true : await this.queuedTransactions(tx.txDataHash);
212 | tx.isQueued = isTxQueued;
213 | resolve(tx);
214 | });
215 | }
216 |
217 | getHistoryTransactionsWithQueuedStatus(): Promise> {
218 | return new Promise(async (resolve, reject) => {
219 | const historyTxList : Array = await this.getHistoryTransactions();
220 | let queuedTxList : Array = [];
221 | for(let i = 0; i < historyTxList.length; i++) {
222 |
223 | const tx = historyTxList[i];
224 | queuedTxList.push(this.queuedTransaction(tx));
225 | }
226 | Promise.all(queuedTxList).then(res => {
227 | resolve(res);
228 | }).catch((error: any) => {
229 | reject(error);
230 | });
231 | });
232 | }
233 |
234 | getHistoryQueueTransactions(): Promise> {
235 | return new Promise(async (resolve, reject) => {
236 | try{
237 | const historyTransactionList : Array = await this.getHistoryTransactionsWithQueuedStatus();
238 | let historyQueueTransactionList : Array = historyTransactionList.filter((tx: ITimelockTransaction) => {
239 | return 'queueTransaction' === tx.decodedFunction.name;
240 | });
241 |
242 | const historyExecuteOrCancelTransactionList : Array = historyTransactionList.filter((tx: ITimelockTransaction) => {
243 | return 'queueTransaction' !== tx.decodedFunction.name;
244 | });
245 |
246 | historyQueueTransactionList = historyQueueTransactionList.map((tx: ITimelockTransaction) => {
247 | const executeOrCancelTransactionList : Array = historyExecuteOrCancelTransactionList.filter((_tx: ITimelockTransaction) => {
248 | return tx.txDataHash == _tx.txDataHash;
249 | });
250 | if(executeOrCancelTransactionList.length > 0) {
251 | tx.executeOrCancelTransaction = executeOrCancelTransactionList[0];
252 | }
253 | return tx;
254 | });
255 |
256 | resolve(historyQueueTransactionList);
257 | }
258 | catch(error) {
259 | reject(error);
260 | }
261 | });
262 | }
263 |
264 | async getAdminAddress(): Promise {
265 | const address: any = await this.trx('admin', []);
266 | return address
267 | }
268 |
269 | }
270 |
271 | export default TimelockHelper;
--------------------------------------------------------------------------------
/timelock/wallet.ts:
--------------------------------------------------------------------------------
1 | declare const ethereum: any
2 |
3 | export async function accountsChanged(cb: Function) {
4 | if (ethereum.isImToken) {
5 | return
6 | }
7 | ethereum.on('accountsChanged', (accounts: any) => {
8 | cb(accounts.length > 0 ? accounts[0] : null)
9 | })
10 | }
11 |
12 | export async function chainChanged(cb: Function) {
13 | if (ethereum.isImToken) {
14 | return
15 | }
16 | ethereum.on('chainChanged', (chainId: string | number) => {
17 | cb(chainId)
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2018",
4 | "module": "esnext",
5 | "moduleResolution": "node",
6 | "resolveJsonModule": true,
7 | "lib": [
8 | "esnext",
9 | "esnext.asynciterable",
10 | "dom"
11 | ],
12 | "esModuleInterop": true,
13 | "allowJs": true,
14 | "sourceMap": true,
15 | "strict": true,
16 | "noEmit": true,
17 | "experimentalDecorators": true,
18 | "baseUrl": ".",
19 | "paths": {
20 | "~/*": [
21 | "./*"
22 | ],
23 | "@/*": [
24 | "./*"
25 | ]
26 | },
27 | "types": [
28 | "@types/node",
29 | "@nuxt/types"
30 | ]
31 | },
32 | "exclude": [
33 | "node_modules",
34 | ".nuxt",
35 | "dist"
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------