@aurigami/sdk 1.6.0-no-src → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
- "version": "1.6.0-no-src",
2
+ "version": "1.6.0",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
6
6
  "files": [
7
- "dist"
7
+ "dist",
8
+ "src"
8
9
  ],
9
10
  "engines": {
10
11
  "node": ">=10"
package/src/SDK.ts ADDED
@@ -0,0 +1,364 @@
1
+ import AuriFairLaunchABI from '@aurigami/contracts/artifacts/contracts/AuriFairLaunch.sol/AuriFairLaunch.json';
2
+ import AuriLensABI from '@aurigami/contracts/artifacts/contracts/AuriLens.sol/AuriLens.json';
3
+ import ComptrollerABI from '@aurigami/contracts/artifacts/contracts/Comptroller.sol/Comptroller.json';
4
+ import FaucetABI from '@aurigami/contracts/artifacts/contracts/mock/Faucet.sol/Faucet.json';
5
+ import {
6
+ AuriFairLaunch,
7
+ AuriLens,
8
+ Comptroller,
9
+ } from '@aurigami/contracts/typechain';
10
+ import { TransactionResponse } from '@ethersproject/abstract-provider';
11
+ import BigNumber from 'bignumber.js';
12
+ import { BigNumber as BN, Contract } from 'ethers';
13
+ import * as consts from './consts';
14
+ import {
15
+ MoneyMarketRead,
16
+ PapermillRead,
17
+ StakingRead,
18
+ StakingReadWrite,
19
+ } from './contracts';
20
+ import {
21
+ BlockchainEntity,
22
+ BlockchainEntityRead,
23
+ Token,
24
+ TokenAmount,
25
+ } from './entities';
26
+ import { decimalFactor, isSameAddress } from './helpers/helpers';
27
+ import { calcValuation, fetchPrice } from './helpers/priceFetcher';
28
+ import * as types from './types';
29
+
30
+ export class SdkRead extends BlockchainEntityRead {
31
+ protected _comptroller: Comptroller;
32
+ protected _auriFairLaunch: AuriFairLaunch;
33
+ protected _auriLens: AuriLens;
34
+ protected _stakingRead: StakingRead;
35
+ constructor(networkConnection: types.NetworkConnection) {
36
+ super(networkConnection);
37
+ this._stakingRead = new StakingRead(networkConnection);
38
+ this._comptroller = new Contract(
39
+ consts.networkAddresses.misc.COMPTROLLER,
40
+ ComptrollerABI.abi,
41
+ networkConnection.provider
42
+ ) as Comptroller;
43
+ this._auriFairLaunch = new Contract(
44
+ consts.networkAddresses.misc.AURIFAIRLAUNCH,
45
+ AuriFairLaunchABI.abi,
46
+ networkConnection.provider
47
+ ) as AuriFairLaunch;
48
+ this._auriLens = new Contract(
49
+ consts.networkAddresses.misc.AURILENS,
50
+ AuriLensABI.abi,
51
+ networkConnection.provider
52
+ ) as AuriLens;
53
+ }
54
+
55
+ public async getUserDetails(userAddress: string): Promise<types.UserDetails> {
56
+ const marketCount = consts.networkAddresses.auTokens.length;
57
+ var userMarketDetails: types.UserMarketDetails[] = [],
58
+ assetsIn: string[];
59
+ var promises = [];
60
+ var totalBorrowLimit = new BigNumber(0);
61
+ var pricePromises = [];
62
+ for (const auToken of consts.networkAddresses.auTokens) {
63
+ const userMarketDetail: types.UserMarketDetails =
64
+ {} as types.UserMarketDetails;
65
+ userMarketDetails.push(userMarketDetail);
66
+ userMarketDetail.market = auToken.underlying;
67
+ const moneyMarket: MoneyMarketRead = new MoneyMarketRead(
68
+ this._networkConnection,
69
+ auToken.address,
70
+ auToken.underlying
71
+ );
72
+ promises.push(
73
+ moneyMarket
74
+ .getUserDepositBalance(userAddress)
75
+ .then((res: TokenAmount) => {
76
+ userMarketDetail.depositBalance = res;
77
+ })
78
+ );
79
+ promises.push(
80
+ moneyMarket
81
+ .getUserBorrowBalance(userAddress)
82
+ .then((res: TokenAmount) => {
83
+ userMarketDetail.borrowBalance = res;
84
+ })
85
+ );
86
+ promises.push(
87
+ moneyMarket.getCollateralRatio().then((res: BigNumber) => {
88
+ userMarketDetail.collateralRatio = res.toNumber();
89
+ })
90
+ );
91
+ pricePromises.push(
92
+ fetchPrice(
93
+ moneyMarket.underlying.address,
94
+ this._networkConnection.provider
95
+ ).then((res) => {
96
+ userMarketDetail.underlyingPrice = res.toString();
97
+ return res;
98
+ })
99
+ );
100
+ }
101
+
102
+ promises.push(
103
+ this._comptroller.getAssetsIn(userAddress).then((res: string[]) => {
104
+ assetsIn = res;
105
+ })
106
+ );
107
+
108
+ await Promise.all(promises);
109
+ var underlyingPrices = await Promise.all(pricePromises);
110
+ var depositValues = [];
111
+ for (var i = 0; i < marketCount; i++) {
112
+ const auToken = consts.networkAddresses.auTokens[i];
113
+ if (
114
+ assetsIn!.find((auAddress: types.Address) =>
115
+ isSameAddress(auToken.address, auAddress)
116
+ ) !== undefined
117
+ ) {
118
+ userMarketDetails[i].isCollateral = true;
119
+ } else {
120
+ userMarketDetails[i].isCollateral = false;
121
+ }
122
+ depositValues.push(
123
+ calcValuation(userMarketDetails[i].depositBalance, underlyingPrices[i])
124
+ );
125
+ }
126
+
127
+ totalBorrowLimit = depositValues.reduce(
128
+ (p: BigNumber, v: BigNumber, index: number) => {
129
+ if (userMarketDetails[index].isCollateral)
130
+ return p.plus(
131
+ v.multipliedBy(userMarketDetails[index].collateralRatio)
132
+ );
133
+ return p;
134
+ },
135
+ new BigNumber(0)
136
+ );
137
+
138
+ var accountLiquidity: [BN, BN] =
139
+ await this._comptroller.getAccountLiquidity(userAddress);
140
+
141
+ var borrowedvaluation: BigNumber = totalBorrowLimit.minus(
142
+ new BigNumber(accountLiquidity[0].toString()).div(decimalFactor(18))
143
+ );
144
+
145
+ if (borrowedvaluation.lt('0.00001')) {
146
+ // Igore dust, dust could be the result of network delay causing collateral valuation calc to be different on vs off chain
147
+ borrowedvaluation = new BigNumber(0);
148
+ }
149
+
150
+ const bufferedBorrowLimit: BigNumber = totalBorrowLimit.multipliedBy(
151
+ consts.BORROW_LIMIT_BUFFER
152
+ );
153
+ const minimumBorrowLimitAllowed = borrowedvaluation.div(
154
+ consts.BORROW_LIMIT_BUFFER
155
+ );
156
+
157
+ var borrowableAmount: BigNumber;
158
+ if (bufferedBorrowLimit.lte(borrowedvaluation)) {
159
+ borrowableAmount = new BigNumber(0);
160
+ } else {
161
+ borrowableAmount = bufferedBorrowLimit.minus(borrowedvaluation);
162
+ }
163
+
164
+ for (var i = 0; i < marketCount; i++) {
165
+ const auToken = consts.networkAddresses.auTokens[i];
166
+ const moneyMarket: MoneyMarketRead = new MoneyMarketRead(
167
+ this._networkConnection,
168
+ auToken.address,
169
+ auToken.underlying
170
+ );
171
+ const borrowLimitMargin = totalBorrowLimit
172
+ .minus(minimumBorrowLimitAllowed)
173
+ .gt(0)
174
+ ? totalBorrowLimit.minus(minimumBorrowLimitAllowed)
175
+ : new BigNumber(0);
176
+ const maxWithdrawCap: BigNumber = borrowLimitMargin
177
+ .div(userMarketDetails[i].collateralRatio)
178
+ .div(underlyingPrices[i]);
179
+ userMarketDetails[i].maxWithdrawableAmount =
180
+ userMarketDetails[i].isCollateral &&
181
+ maxWithdrawCap.lt(userMarketDetails[i].depositBalance.formattedAmount())
182
+ ? new TokenAmount(
183
+ moneyMarket.underlying,
184
+ maxWithdrawCap.toFixed(24),
185
+ false
186
+ )
187
+ : new TokenAmount(
188
+ moneyMarket.underlying,
189
+ userMarketDetails[i].depositBalance.rawAmount()
190
+ );
191
+ }
192
+
193
+ return {
194
+ markets: userMarketDetails,
195
+ borrowLimit: {
196
+ currency: 'USD',
197
+ amount: bufferedBorrowLimit.toFixed(consts.DECIMAL_PRECISION),
198
+ },
199
+ userLockingDetails: await new PapermillRead(
200
+ this._networkConnection
201
+ ).getLockingDetails(userAddress),
202
+ borrowableAmount: {
203
+ currency: 'USD',
204
+ amount: borrowableAmount.toFixed(consts.DECIMAL_PRECISION),
205
+ },
206
+ };
207
+ }
208
+
209
+ public async getPLYWNEARPoolDetails(): Promise<types.PLYWNEARPoolDetails> {
210
+ return this._stakingRead.getPLYWNEARPoolDetails();
211
+ }
212
+
213
+ public async getTokenPrice(token: Token): Promise<types.CurrencyAmount> {
214
+ const price = await fetchPrice(
215
+ token.address,
216
+ this._networkConnection.provider
217
+ );
218
+ return {
219
+ currency: 'USD',
220
+ amount: price.toFixed(consts.DECIMAL_PRECISION),
221
+ };
222
+ }
223
+
224
+ /**
225
+ * Get amount of staked LP tokens
226
+ */
227
+ public async stakeBalanceOf(user: string): Promise<TokenAmount> {
228
+ return this._stakingRead.stakeBalanceOf(user);
229
+ }
230
+
231
+ /**
232
+ * Get amount of LP token in user wallet
233
+ */
234
+ public async LpBalanceOf(user: string): Promise<TokenAmount> {
235
+ return this._stakingRead.LpBalanceOf(user);
236
+ }
237
+
238
+ public async unclaimedRewardsOf(user: string): Promise<TokenAmount[]> {
239
+ return this._stakingRead.unclaimedRewardsOf(user);
240
+ }
241
+
242
+ public calcHypotheticalStats({
243
+ userMarketDetail,
244
+ currentBorrowLimit,
245
+ currentBorrowValuation,
246
+ action,
247
+ tokenAmount,
248
+ }: {
249
+ userMarketDetail: types.UserMarketDetails;
250
+ currentBorrowLimit: types.CurrencyAmount;
251
+ currentBorrowValuation: types.CurrencyAmount;
252
+ action: types.MarketAction;
253
+ tokenAmount?: TokenAmount;
254
+ }): types.HypotheticalStats {
255
+ var newBorrowLimit = new BigNumber(currentBorrowLimit.amount),
256
+ newBorrowValuation = new BigNumber(currentBorrowValuation.amount);
257
+ switch (action) {
258
+ case types.MarketAction.EnableCollateral:
259
+ case types.MarketAction.DisableCollateral:
260
+ var deltaBorrowLimit = calcValuation(
261
+ userMarketDetail.depositBalance,
262
+ new BigNumber(userMarketDetail.underlyingPrice)
263
+ )
264
+ .multipliedBy(userMarketDetail.collateralRatio)
265
+ .multipliedBy(consts.BORROW_LIMIT_BUFFER);
266
+ newBorrowLimit =
267
+ action == types.MarketAction.EnableCollateral
268
+ ? newBorrowLimit.plus(deltaBorrowLimit)
269
+ : newBorrowLimit.minus(deltaBorrowLimit);
270
+ break;
271
+
272
+ case types.MarketAction.Deposit:
273
+ case types.MarketAction.Withdraw:
274
+ deltaBorrowLimit = calcValuation(
275
+ tokenAmount!,
276
+ new BigNumber(userMarketDetail.underlyingPrice)
277
+ )
278
+ .multipliedBy(userMarketDetail.collateralRatio)
279
+ .multipliedBy(consts.BORROW_LIMIT_BUFFER);
280
+ newBorrowLimit =
281
+ action == types.MarketAction.Deposit
282
+ ? newBorrowLimit.plus(deltaBorrowLimit)
283
+ : newBorrowLimit.minus(deltaBorrowLimit);
284
+ break;
285
+
286
+ case types.MarketAction.Borrow:
287
+ case types.MarketAction.Repay:
288
+ var deltaBorrowValuation = calcValuation(
289
+ tokenAmount!,
290
+ new BigNumber(userMarketDetail.underlyingPrice)
291
+ );
292
+ newBorrowValuation =
293
+ action == types.MarketAction.Borrow
294
+ ? newBorrowValuation.plus(deltaBorrowValuation)
295
+ : newBorrowValuation.minus(deltaBorrowValuation);
296
+ break;
297
+ }
298
+ return {
299
+ newBorrowLimit: {
300
+ amount: newBorrowLimit!.toFixed(consts.DECIMAL_PRECISION),
301
+ currency: 'USD',
302
+ },
303
+ newBorrowUtilization: newBorrowLimit.eq(0)
304
+ ? newBorrowValuation.eq(0)
305
+ ? 0
306
+ : 9999.99
307
+ : newBorrowValuation!.div(newBorrowLimit!).toNumber(),
308
+ };
309
+ }
310
+ }
311
+
312
+ export class SdkReadWrite extends SdkRead {
313
+ /**
314
+ * Claim PLY reward in all markets + staking pools
315
+ */
316
+ public async claim(): Promise<TransactionResponse> {
317
+ return this._comptroller
318
+ .connect(this._networkConnection.signer!)
319
+ ['claimReward(uint8,address)'](
320
+ 0,
321
+ await this._networkConnection.signer!.getAddress()
322
+ );
323
+ }
324
+
325
+ public async claimLpRewards(): Promise<TransactionResponse> {
326
+ return this._auriFairLaunch
327
+ .connect(this._networkConnection.signer!)
328
+ .harvest(
329
+ await this._networkConnection.signer!.getAddress(),
330
+ 0,
331
+ consts.INF
332
+ );
333
+ }
334
+
335
+ public async stake(amount: TokenAmount): Promise<TransactionResponse> {
336
+ return new StakingReadWrite(this._networkConnection).stake(amount);
337
+ }
338
+
339
+ public async unstake(amount: TokenAmount): Promise<TransactionResponse> {
340
+ return new StakingReadWrite(this._networkConnection).unstake(amount);
341
+ }
342
+
343
+ public async faucetDrip(): Promise<TransactionResponse> {
344
+ const faucet = new Contract(
345
+ consts.networkAddresses.misc.FAUCET,
346
+ FaucetABI.abi,
347
+ this._networkConnection.provider
348
+ );
349
+ return faucet.connect(this._networkConnection.signer!).drip();
350
+ }
351
+ }
352
+
353
+ export class SDK extends BlockchainEntity {
354
+ constructor() {
355
+ super();
356
+ }
357
+ public read(networkConnection: types.NetworkConnection): SdkRead {
358
+ return new SdkRead(networkConnection);
359
+ }
360
+
361
+ public readWrite(networkConnection: types.NetworkConnection): SdkReadWrite {
362
+ return new SdkReadWrite(networkConnection);
363
+ }
364
+ }
@@ -0,0 +1,157 @@
1
+ {
2
+ "_format": "hh-sol-artifact-1",
3
+ "contractName": "Faucet",
4
+ "sourceName": "contracts/mock/Faucet.sol",
5
+ "abi": [
6
+ {
7
+ "inputs": [
8
+ {
9
+ "components": [
10
+ {
11
+ "internalType": "address",
12
+ "name": "token",
13
+ "type": "address"
14
+ },
15
+ {
16
+ "internalType": "uint256",
17
+ "name": "dripAmount",
18
+ "type": "uint256"
19
+ }
20
+ ],
21
+ "internalType": "struct Faucet.TokenConfig[]",
22
+ "name": "_testTokensConfigs",
23
+ "type": "tuple[]"
24
+ }
25
+ ],
26
+ "stateMutability": "nonpayable",
27
+ "type": "constructor"
28
+ },
29
+ {
30
+ "anonymous": false,
31
+ "inputs": [
32
+ {
33
+ "indexed": true,
34
+ "internalType": "address",
35
+ "name": "previousOwner",
36
+ "type": "address"
37
+ },
38
+ {
39
+ "indexed": true,
40
+ "internalType": "address",
41
+ "name": "newOwner",
42
+ "type": "address"
43
+ }
44
+ ],
45
+ "name": "OwnershipTransferred",
46
+ "type": "event"
47
+ },
48
+ {
49
+ "inputs": [],
50
+ "name": "drip",
51
+ "outputs": [],
52
+ "stateMutability": "nonpayable",
53
+ "type": "function"
54
+ },
55
+ {
56
+ "inputs": [
57
+ {
58
+ "internalType": "address",
59
+ "name": "",
60
+ "type": "address"
61
+ }
62
+ ],
63
+ "name": "dripAmounts",
64
+ "outputs": [
65
+ {
66
+ "internalType": "uint256",
67
+ "name": "",
68
+ "type": "uint256"
69
+ }
70
+ ],
71
+ "stateMutability": "view",
72
+ "type": "function"
73
+ },
74
+ {
75
+ "inputs": [],
76
+ "name": "owner",
77
+ "outputs": [
78
+ {
79
+ "internalType": "address",
80
+ "name": "",
81
+ "type": "address"
82
+ }
83
+ ],
84
+ "stateMutability": "view",
85
+ "type": "function"
86
+ },
87
+ {
88
+ "inputs": [],
89
+ "name": "renounceOwnership",
90
+ "outputs": [],
91
+ "stateMutability": "nonpayable",
92
+ "type": "function"
93
+ },
94
+ {
95
+ "inputs": [
96
+ {
97
+ "internalType": "uint256",
98
+ "name": "",
99
+ "type": "uint256"
100
+ }
101
+ ],
102
+ "name": "testTokens",
103
+ "outputs": [
104
+ {
105
+ "internalType": "address",
106
+ "name": "",
107
+ "type": "address"
108
+ }
109
+ ],
110
+ "stateMutability": "view",
111
+ "type": "function"
112
+ },
113
+ {
114
+ "inputs": [
115
+ {
116
+ "internalType": "address",
117
+ "name": "newOwner",
118
+ "type": "address"
119
+ }
120
+ ],
121
+ "name": "transferOwnership",
122
+ "outputs": [],
123
+ "stateMutability": "nonpayable",
124
+ "type": "function"
125
+ },
126
+ {
127
+ "inputs": [
128
+ {
129
+ "components": [
130
+ {
131
+ "internalType": "address",
132
+ "name": "token",
133
+ "type": "address"
134
+ },
135
+ {
136
+ "internalType": "uint256",
137
+ "name": "dripAmount",
138
+ "type": "uint256"
139
+ }
140
+ ],
141
+ "internalType": "struct Faucet.TokenConfig[]",
142
+ "name": "_testTokensConfigs",
143
+ "type": "tuple[]"
144
+ }
145
+ ],
146
+ "name": "updateTokenConfigs",
147
+ "outputs": [],
148
+ "stateMutability": "nonpayable",
149
+ "type": "function"
150
+ }
151
+ ],
152
+ "bytecode": "0x60806040523480156200001157600080fd5b5060405162000c4038038062000c40833981016040819052620000349162000272565b6200003f33620000f9565b60005b8151811015620000f1576200007d82828151811062000065576200006562000363565b6020026020010151600001516200014960201b60201c565b81818151811062000092576200009262000363565b60200260200101516020015160026000848481518110620000b757620000b762000363565b602090810291909101810151516001600160a01b031682528101919091526040016000205580620000e88162000379565b91505062000042565b5050620003a3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b600154811015620001ac57816001600160a01b03166001828154811062000177576200017762000363565b6000918252602090912001546001600160a01b0316141562000197575050565b80620001a38162000379565b9150506200014c565b506001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0392909216919091179055565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620002395762000239620001fe565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200026a576200026a620001fe565b604052919050565b600060208083850312156200028657600080fd5b82516001600160401b03808211156200029e57600080fd5b818501915085601f830112620002b357600080fd5b815181811115620002c857620002c8620001fe565b620002d8848260051b016200023f565b818152848101925060069190911b830184019087821115620002f957600080fd5b928401925b81841015620003585760408489031215620003195760008081fd5b6200032362000214565b84516001600160a01b03811681146200033c5760008081fd5b81528486015186820152835260409093019291840191620002fe565b979650505050505050565b634e487b7160e01b600052603260045260246000fd5b60006000198214156200039c57634e487b7160e01b600052601160045260246000fd5b5060010190565b61088d80620003b36000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80639f678cca1161005b5780639f678cca146100c9578063b9293286146100d1578063e980416a146100e4578063f2fde38b1461011257600080fd5b8063715018a614610082578063741f83ef1461008c5780638da5cb5b1461009f575b600080fd5b61008a610125565b005b61008a61009a366004610697565b610190565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b61008a61028b565b6100ac6100df36600461076b565b6103a2565b6101046100f2366004610784565b60026020526000908152604090205481565b6040519081526020016100c0565b61008a610120366004610784565b6103cc565b6000546001600160a01b031633146101845760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61018e60006104a7565b565b6000546001600160a01b031633146101ea5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161017b565b60005b81518110156102875761021c82828151811061020b5761020b6107a6565b60200260200101516000015161050f565b81818151811061022e5761022e6107a6565b60200260200101516020015160026000848481518110610250576102506107a6565b602090810291909101810151516001600160a01b03168252810191909152604001600020558061027f816107d5565b9150506101ed565b5050565b60005b60015481101561039f57600181815481106102ab576102ab6107a6565b6000918252602082200154600180546001600160a01b039092169263a9059cbb92339260029291879081106102e2576102e26107a6565b6000918252602080832091909101546001600160a01b039081168452908301939093526040918201902054905160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815292909116600483015260248201526044016020604051808303816000875af1158015610368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038c9190610835565b5080610397816107d5565b91505061028e565b50565b600181815481106103b257600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b031633146104265760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161017b565b6001600160a01b0381166104a25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161017b565b61039f815b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b60015481101561056a57816001600160a01b031660018281548110610539576105396107a6565b6000918252602090912001546001600160a01b03161415610558575050565b80610562816107d5565b915050610512565b506001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610626576106266105d4565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610673576106736105d4565b604052919050565b80356001600160a01b038116811461069257600080fd5b919050565b600060208083850312156106aa57600080fd5b823567ffffffffffffffff808211156106c257600080fd5b818501915085601f8301126106d657600080fd5b8135818111156106e8576106e86105d4565b6106f6848260051b0161062c565b818152848101925060069190911b83018401908782111561071657600080fd5b928401925b8184101561076057604084890312156107345760008081fd5b61073c610603565b6107458561067b565b8152848601358682015283526040909301929184019161071b565b979650505050505050565b60006020828403121561077d57600080fd5b5035919050565b60006020828403121561079657600080fd5b61079f8261067b565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561082e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60006020828403121561084757600080fd5b8151801515811461079f57600080fdfea26469706673582212200b56248e3867f8c6afaf02091fa7b57d47168960cfdfc133122e492377adaa3264736f6c634300080b0033",
153
+ "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c80639f678cca1161005b5780639f678cca146100c9578063b9293286146100d1578063e980416a146100e4578063f2fde38b1461011257600080fd5b8063715018a614610082578063741f83ef1461008c5780638da5cb5b1461009f575b600080fd5b61008a610125565b005b61008a61009a366004610697565b610190565b6000546001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b61008a61028b565b6100ac6100df36600461076b565b6103a2565b6101046100f2366004610784565b60026020526000908152604090205481565b6040519081526020016100c0565b61008a610120366004610784565b6103cc565b6000546001600160a01b031633146101845760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b61018e60006104a7565b565b6000546001600160a01b031633146101ea5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161017b565b60005b81518110156102875761021c82828151811061020b5761020b6107a6565b60200260200101516000015161050f565b81818151811061022e5761022e6107a6565b60200260200101516020015160026000848481518110610250576102506107a6565b602090810291909101810151516001600160a01b03168252810191909152604001600020558061027f816107d5565b9150506101ed565b5050565b60005b60015481101561039f57600181815481106102ab576102ab6107a6565b6000918252602082200154600180546001600160a01b039092169263a9059cbb92339260029291879081106102e2576102e26107a6565b6000918252602080832091909101546001600160a01b039081168452908301939093526040918201902054905160e085901b7fffffffff0000000000000000000000000000000000000000000000000000000016815292909116600483015260248201526044016020604051808303816000875af1158015610368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038c9190610835565b5080610397816107d5565b91505061028e565b50565b600181815481106103b257600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b031633146104265760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161017b565b6001600160a01b0381166104a25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161017b565b61039f815b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b60015481101561056a57816001600160a01b031660018281548110610539576105396107a6565b6000918252602090912001546001600160a01b03161415610558575050565b80610562816107d5565b915050610512565b506001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610626576106266105d4565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610673576106736105d4565b604052919050565b80356001600160a01b038116811461069257600080fd5b919050565b600060208083850312156106aa57600080fd5b823567ffffffffffffffff808211156106c257600080fd5b818501915085601f8301126106d657600080fd5b8135818111156106e8576106e86105d4565b6106f6848260051b0161062c565b818152848101925060069190911b83018401908782111561071657600080fd5b928401925b8184101561076057604084890312156107345760008081fd5b61073c610603565b6107458561067b565b8152848601358682015283526040909301929184019161071b565b979650505050505050565b60006020828403121561077d57600080fd5b5035919050565b60006020828403121561079657600080fd5b61079f8261067b565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561082e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b60006020828403121561084757600080fd5b8151801515811461079f57600080fdfea26469706673582212200b56248e3867f8c6afaf02091fa7b57d47168960cfdfc133122e492377adaa3264736f6c634300080b0033",
154
+ "linkReferences": {},
155
+ "deployedLinkReferences": {}
156
+ }
157
+