diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 321219553..c0ffaedaf 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -1,31 +1,32 @@ name: Checks on: - - pull_request + - pull_request jobs: - Build: - env: - BALANCER_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx - MASTERCHEF_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/masterchefv2 - BLOCKS_SUBGRAPH: https://api.thegraph.com/subgraphs/name/danielmkm/optimism-blocks - BEETS_BAR_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/beets-bar - USER_SNAPSHOT_SUBGRAPH: https://api.thegraph.com/subgraphs/name/danielmkm/user-balances-fantom - GAUGE_SUBGRAPH: https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges-optimism - VEBALLOCKS_SUBGRAPH: https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges - RELIQUARY_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/reliquary - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: '18.x' - - name: Install deps - run: yarn - - name: Generate Schema - run: yarn generate - - name: Prisma Generate - run: yarn prisma generate - - name: Run build - run: yarn build + Build: + env: + BALANCER_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx + MASTERCHEF_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/masterchefv2 + BLOCKS_SUBGRAPH: https://api.thegraph.com/subgraphs/name/danielmkm/optimism-blocks + BEETS_BAR_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/beets-bar + USER_SNAPSHOT_SUBGRAPH: https://api.thegraph.com/subgraphs/name/danielmkm/user-balances-fantom + GAUGE_SUBGRAPH: https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges-optimism + VEBALLOCKS_SUBGRAPH: https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges + RELIQUARY_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/reliquary + SFTMX_SUBGRAPH: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/sftmx' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: '18.x' + - name: Install deps + run: yarn + - name: Generate Schema + run: yarn generate + - name: Prisma Generate + run: yarn prisma generate + - name: Run build + run: yarn build diff --git a/buildspec.yml b/buildspec.yml index 047371c61..3b9a1e090 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -11,6 +11,7 @@ env: GAUGE_SUBGRAPH: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges-optimism' USER_SNAPSHOT_SUBGRAPH: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/user-bpt-balances-fantom' VEBALLOCKS_SUBGRAPH: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges' + SFTMX_SUBGRAPH: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/sftmx' phases: install: runtime-versions: diff --git a/codegen.yml b/codegen.yml index 57c4ff13b..b6d7a4a77 100644 --- a/codegen.yml +++ b/codegen.yml @@ -53,6 +53,24 @@ generates: schema: ${RELIQUARY_SUBGRAPH} plugins: - schema-ast + modules/subgraphs/sftmx-subgraph/generated/sftmx-subgraph-types.ts: + schema: ${SFTMX_SUBGRAPH} + documents: 'modules/subgraphs/sftmx-subgraph/sftmx-subgraph-queries.graphql' + plugins: + - typescript + - typescript-operations + - typescript-graphql-request + config: + scalars: + BigInt: string + Bytes: string + BigDecimal: string + namingConvention: + enumValues: keep + modules/subgraphs/sftmx-subgraph/generated/sftmx-subgraph-schema.graphql: + schema: ${SFTMX_SUBGRAPH} + plugins: + - schema-ast modules/subgraphs/blocks-subgraph/generated/blocks-subgraph-types.ts: schema: ${BLOCKS_SUBGRAPH} documents: 'modules/subgraphs/blocks-subgraph/block-subgraph-queries.graphql' diff --git a/env.local b/env.local index fb4c4c67c..2fb1bba94 100644 --- a/env.local +++ b/env.local @@ -24,6 +24,7 @@ USER_SNAPSHOT_SUBGRAPH=https://api.thegraph.com/subgraphs/name/danielmkm/user-ba GAUGE_SUBGRAPH=https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges-optimism VEBALLOCKS_SUBGRAPH=https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges RELIQUARY_SUBGRAPH=https://api.thegraph.com/subgraphs/name/beethovenxfi/reliquary +SFTMX_SUBGRAPH=https://api.thegraph.com/subgraphs/name/beethovenxfi/sftmx # CRM SANITY_API_TOKEN= diff --git a/modules/network/apr-config-types.ts b/modules/network/apr-config-types.ts index d4bdb5a37..93b9c8ac0 100644 --- a/modules/network/apr-config-types.ts +++ b/modules/network/apr-config-types.ts @@ -3,6 +3,7 @@ export interface IbAprConfig { ankr?: AnkrAprConfig; bloom?: BloomAprConfig; beefy?: BeefyAprConfig; + sftmx?: SftmxAprConfig; euler?: EulerAprConfig; gearbox?: GearBoxAprConfig; idle?: IdleAprConfig; @@ -67,6 +68,15 @@ export interface BloomAprConfig { }; } +export interface SftmxAprConfig { + tokens: { + [underlyingAssetName: string]: { + address: string; + ftmStakingAddress: string; + }; + }; +} + export interface EulerAprConfig { subgraphUrl: string; tokens: { diff --git a/modules/network/fantom.ts b/modules/network/fantom.ts index fbae4a3e0..22727cf81 100644 --- a/modules/network/fantom.ts +++ b/modules/network/fantom.ts @@ -27,6 +27,7 @@ import { env } from '../../app/env'; import { IbTokensAprService } from '../pool/lib/apr-data-sources/ib-tokens-apr.service'; import { BeetswarsGaugeVotingAprService } from '../pool/lib/apr-data-sources/fantom/beetswars-gauge-voting-apr'; import { BalancerSubgraphService } from '../subgraphs/balancer-subgraph/balancer-subgraph.service'; +import { SftmxSubgraphService } from '../subgraphs/sftmx-subgraph/sftmx.service'; const fantomNetworkData: NetworkData = { chain: { @@ -45,6 +46,7 @@ const fantomNetworkData: NetworkData = { masterchef: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/masterchefv2', reliquary: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/reliquary', userBalances: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/user-bpt-balances-fantom', + sftmx: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/sftmx', }, eth: { address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', @@ -94,7 +96,8 @@ const fantomNetworkData: NetworkData = { tokenPrices: { maxHourlyPriceHistoryNumDays: 100, }, - rpcUrl: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'main' + rpcUrl: + (env.DEPLOYMENT_ENV as DeploymentEnv) === 'main' ? `https://rpc.ankr.com/fantom` : `https://rpc.fantom.gateway.fm`, rpcMaxBlockRange: 1000, @@ -107,6 +110,10 @@ const fantomNetworkData: NetworkData = { address: '0xf24bcf4d1e507740041c9cfd2dddb29585adce1e', beetsPriceProviderRpcUrl: 'https://rpc.ftm.tools', }, + sftmx: { + stakingContractAddress: '0xb458bfc855ab504a8a327720fcef98886065529b', + sftmxAddress: '0xd7028092c830b5c8fce061af2e593413ebbc1fc1', + }, fbeets: { address: '0xfcef8a994209d6916eb2c86cdd2afd60aa6f54b1', farmId: '22', @@ -171,6 +178,14 @@ const fantomNetworkData: NetworkData = { }, }, }, + // sftmx: { + // tokens: { + // sftmx: { + // address: '0xd7028092c830b5c8fce061af2e593413ebbc1fc1', + // ftmStakingAddress: '0xb458bfc855ab504a8a327720fcef98886065529b', + // }, + // }, + // }, reaper: { subgraphSource: { subgraphUrl: 'https://api.thegraph.com/subgraphs/name/byte-masons/multi-strategy-vaults-fantom', @@ -333,6 +348,7 @@ export const fantomNetworkConfig: NetworkConfig = { fantomNetworkData.subgraphs.balancer, fantomNetworkData.chain.id, ), + sftmxSubgraphService: new SftmxSubgraphService(fantomNetworkData.subgraphs.sftmx!), }, /* For sub-minute jobs we set the alarmEvaluationPeriod and alarmDatapointsToAlarm to 1 instead of the default 3. @@ -444,5 +460,13 @@ export const fantomNetworkConfig: NetworkConfig = { name: 'feed-data-to-datastudio', interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(5, 'minutes'), }, + { + name: 'sync-sftmx-staking-data', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(60, 'minutes') : every(30, 'minutes'), + }, + { + name: 'sync-sftmx-withdrawal-requests', + interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(30, 'minutes') : every(5, 'minutes'), + }, ], }; diff --git a/modules/network/network-config-types.ts b/modules/network/network-config-types.ts index da2886395..6bf9ffe5d 100644 --- a/modules/network/network-config-types.ts +++ b/modules/network/network-config-types.ts @@ -6,8 +6,9 @@ import { TokenPriceHandler } from '../token/token-types'; import { BaseProvider } from '@ethersproject/providers'; import { GqlChain } from '../../schema'; import { ContentService } from '../content/content-types'; -import { AaveAprConfig, IbAprConfig } from './apr-config-types'; +import { IbAprConfig } from './apr-config-types'; import { BalancerSubgraphService } from '../subgraphs/balancer-subgraph/balancer-subgraph.service'; +import { SftmxSubgraphService } from '../subgraphs/sftmx-subgraph/sftmx.service'; export interface NetworkConfig { data: NetworkData; @@ -23,6 +24,7 @@ export interface NetworkConfig { interface NetworkServices { balancerSubgraphService: BalancerSubgraphService; + sftmxSubgraphService?: SftmxSubgraphService; } export interface WorkerJob { @@ -69,6 +71,7 @@ export interface NetworkData { blocks: string; masterchef?: string; reliquary?: string; + sftmx?: string; beetsBar?: string; gauge?: string; veBalLocks?: string; @@ -89,6 +92,10 @@ export interface NetworkData { poolId: string; poolAddress: string; }; + sftmx?: { + stakingContractAddress: string; + sftmxAddress: string; + }; bal?: { address: string; }; diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/ib-linear-apr-handlers.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/ib-linear-apr-handlers.ts index 4f399d649..adea7ee34 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/ib-linear-apr-handlers.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/ib-linear-apr-handlers.ts @@ -7,6 +7,7 @@ const sourceToHandler = { ankr: sources.AnkrAprHandler, beefy: sources.BeefyAprHandler, bloom: sources.BloomAprHandler, + sftmx: sources.SftmxAprHandler, euler: sources.EulerAprHandler, gearbox: sources.GearboxAprHandler, idle: sources.IdleAprHandler, @@ -18,7 +19,7 @@ const sourceToHandler = { tranchess: sources.TranchessAprHandler, yearn: sources.YearnAprHandler, defaultHandlers: sources.DefaultAprHandler, -} +}; export class IbLinearAprHandlers { private handlers: AprHandler[] = []; @@ -49,11 +50,11 @@ export class IbLinearAprHandlers { // Add handlers from self-configured sources Object.values(sources as unknown as any[]) - .filter((source): source is { chains: Chain[], Handler: AprHandlerConstructor } => 'chains' in source) + .filter((source): source is { chains: Chain[]; Handler: AprHandlerConstructor } => 'chains' in source) .filter((source) => this.chain && source.chains.includes(this.chain)) .forEach((source) => { handlers.push(new source.Handler()); - }); + }); return handlers; } @@ -61,11 +62,11 @@ export class IbLinearAprHandlers { async fetchAprsFromAllHandlers(): Promise { let aprs: TokenApr[] = this.fixedAprTokens ? Object.values(this.fixedAprTokens).map(({ address, apr, isIbYield, group }) => ({ - apr, - address, - isIbYield: isIbYield ?? false, - group - })) + apr, + address, + isIbYield: isIbYield ?? false, + group, + })) : []; const results = await Promise.allSettled(this.handlers.map((handler) => handler.getAprs(this.chain))); @@ -77,7 +78,7 @@ export class IbLinearAprHandlers { apr, address, isIbYield, - group + group, })), ); } else { @@ -99,9 +100,9 @@ export interface AprHandler { [tokenAddress: string]: { /** Defined as float, eg: 0.01 is 1% */ apr: number; - isIbYield: boolean + isIbYield: boolean; group?: string; - } + }; }>; } diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/index.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/index.ts index 94a5dff90..19f3c7453 100644 --- a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/index.ts +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/index.ts @@ -1,5 +1,6 @@ export * from './aave-apr-handler'; export * from './ankr-apr-handler'; +export * from './sftmx-apr-handler'; export * from './default-apr-handler'; export * from './euler-apr-handler'; export * from './gearbox-apr-handler'; diff --git a/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/sftmx-apr-handler.ts b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/sftmx-apr-handler.ts new file mode 100644 index 000000000..6c805269e --- /dev/null +++ b/modules/pool/lib/apr-data-sources/ib-linear-apr-handlers/sources/sftmx-apr-handler.ts @@ -0,0 +1,83 @@ +import * as Sentry from '@sentry/node'; +import { AprHandler } from '../ib-linear-apr-handlers'; +import { SftmxAprConfig } from '../../../../../network/apr-config-types'; +import { BigNumber, ethers } from 'ethers'; +import { getContractAt } from '../../../../../web3/contract'; +import FTMStaking from '../../../../../sftmx/abi/FTMStaking.json'; +import Vault from '../../../../../sftmx/abi/Vault.json'; +import { formatFixed } from '@ethersproject/bignumber'; + +export class SftmxAprHandler implements AprHandler { + tokens: { + [underlyingAssetName: string]: { + address: string; + ftmStakingAddress: string; + }; + }; + + constructor(config: SftmxAprConfig) { + this.tokens = config.tokens; + } + + async getAprs(): Promise<{ + [tokenAddress: string]: { + /** Defined as float, eg: 0.01 is 1% */ + apr: number; + isIbYield: boolean; + group?: string; + }; + }> { + const baseApr = 0.018; + const maxLockApr = 0.06; + const validatorFee = 0.15; + const sftmxFee = 0.1; + try { + const aprs: { + [tokenAddress: string]: { + apr: number; + isIbYield: boolean; + group?: string; + }; + } = {}; + + for (const tokenAddress in this.tokens) { + const tokenDefinition = this.tokens[tokenAddress]; + const ftmStakingContract = getContractAt(tokenDefinition.ftmStakingAddress, FTMStaking.abi); + + const totalFtm = (await ftmStakingContract.totalFTMWorth()) as BigNumber; + const poolFtm = (await ftmStakingContract.getPoolBalance()) as BigNumber; + const maturedVaultCount = await ftmStakingContract.getMaturedVaultLength(); + + let maturedFtmAmount = BigNumber.from('0'); + + for (let i = 0; i < maturedVaultCount; i++) { + const vaultAddress = await ftmStakingContract.getMaturedVault(i); + const vaultContract = getContractAt(vaultAddress, Vault.abi); + const vaultAmount = await vaultContract.currentStakeValue(); + maturedFtmAmount = maturedFtmAmount.add(vaultAmount); + } + + const totalFtmNum = parseFloat(formatFixed(totalFtm.toString(), 18)); + const poolFtmNum = parseFloat(formatFixed(poolFtm.toString(), 18)); + const maturedFtmNum = parseFloat(formatFixed(maturedFtmAmount.toString(), 18)); + const stakedFtmNum = totalFtmNum - poolFtmNum - maturedFtmNum; + + const totalMaxLockApr = + (stakedFtmNum / totalFtmNum) * (maxLockApr * (1 - validatorFee)) * (1 - sftmxFee); + const totalBaseApr = (maturedFtmNum / totalFtmNum) * (baseApr * (1 - validatorFee)) * (1 - sftmxFee); + + const totalSftmxApr = totalMaxLockApr + totalBaseApr; + + aprs[tokenDefinition.address] = { + apr: totalSftmxApr, + isIbYield: true, + }; + } + return aprs; + } catch (error) { + console.error('Failed to fetch sftmx APR:', error); + Sentry.captureException(`sftmx IB APR handler failed: ${error}`); + return {}; + } + } +} diff --git a/modules/sftmx/abi/FTMStaking.json b/modules/sftmx/abi/FTMStaking.json new file mode 100644 index 000000000..ca5e6341b --- /dev/null +++ b/modules/sftmx/abi/FTMStaking.json @@ -0,0 +1,1314 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "FTMStaking", + "sourceName": "contracts/FTMStaking.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "low", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "high", + "type": "uint256" + } + ], + "name": "LogDepositLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ftmxAmount", + "type": "uint256" + } + ], + "name": "LogDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "duration", + "type": "uint256" + } + ], + "name": "LogEpochDurationSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lockupDuration", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LogLocked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "newValue", + "type": "bool" + } + ], + "name": "LogMaintenancePausedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "newValue", + "type": "bool" + } + ], + "name": "LogUndelegatePausedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wrID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountFTMx", + "type": "uint256" + } + ], + "name": "LogUndelegated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "validatorPicker", + "type": "address" + } + ], + "name": "LogValidatorPickerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maturedIndex", + "type": "uint256" + } + ], + "name": "LogVaultHarvested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "LogVaultOwnerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + } + ], + "name": "LogVaultWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "newValue", + "type": "bool" + } + ], + "name": "LogWithdrawPausedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "delay", + "type": "uint256" + } + ], + "name": "LogWithdrawalDelaySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "wrID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bitmaskToSkip", + "type": "uint256" + } + ], + "name": "LogWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "inputs": [], + "name": "DECIMAL_UNIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "FTMX", + "outputs": [ + { + "internalType": "contract IERC20Burnable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_LOCKUP_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SFC", + "outputs": [ + { + "internalType": "contract ISFC", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UNLOCKED_REWARD_RATIO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allWithdrawalRequests", + "outputs": [ + { + "internalType": "uint256", + "name": "requestTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "undelegateAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "penalty", + "type": "uint256" + }, + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWithdrawn", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amountFTMx", + "type": "uint256" + } + ], + "name": "calculatePenalty", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimRewardsAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "currentVaultCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentVaultPtr", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "epochDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ftmPendingWithdrawal", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getExchangeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ftmAmount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "toIgnore", + "type": "bool" + } + ], + "name": "getFTMxAmountForFTM", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultIndex", + "type": "uint256" + } + ], + "name": "getMaturedVault", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaturedVaultLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPoolBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultIndex", + "type": "uint256" + } + ], + "name": "getVault", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wrID", + "type": "uint256" + } + ], + "name": "getWithdrawalInfo", + "outputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "vault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountToUnlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountToUndelegate", + "type": "uint256" + } + ], + "internalType": "struct FTMStaking.UndelegateInfo[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultIndex", + "type": "uint256" + } + ], + "name": "harvestVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Burnable", + "name": "_ftmx_", + "type": "address" + }, + { + "internalType": "contract ISFC", + "name": "_sfc_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxVaultCount_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "epochDuration_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "withdrawalDelay_", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastKnownEpoch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "lock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maintenancePaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxVaultCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextEligibleTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "pickVaultsToUndelegate", + "outputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "vault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountToUnlock", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountToUndelegate", + "type": "uint256" + } + ], + "internalType": "struct FTMStaking.UndelegateInfo[]", + "name": "", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeeBIPS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "low", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "high", + "type": "uint256" + } + ], + "name": "setDepositLimits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + } + ], + "name": "setEpochDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "desiredValue", + "type": "bool" + } + ], + "name": "setMaintenancePaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newFeeBIPS", + "type": "uint256" + } + ], + "name": "setProtocolFeeBIPS", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newTreasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "desiredValue", + "type": "bool" + } + ], + "name": "setUndelegatePaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IValidatorPicker", + "name": "picker", + "type": "address" + } + ], + "name": "setValidatorPicker", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "desiredValue", + "type": "bool" + } + ], + "name": "setWithdrawPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "delay", + "type": "uint256" + } + ], + "name": "setWithdrawalDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalFTMWorth", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wrID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountFTMx", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minAmountFTM", + "type": "uint256" + } + ], + "name": "undelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "undelegatePaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "vault", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "updateVaultOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "validatorPicker", + "outputs": [ + { + "internalType": "contract IValidatorPicker", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wrID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bitmaskToSkip", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maturedIndex", + "type": "uint256" + } + ], + "name": "withdrawMatured", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalDelay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x60a06040523060601b6080523480156200001857600080fd5b50600054610100900460ff16158080156200003a5750600054600160ff909116105b806200006a575062000057306200014460201b62002e321760201c565b1580156200006a575060005460ff166001145b620000d25760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000f6576000805461ff0019166101001790555b80156200013d576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5062000153565b6001600160a01b03163b151590565b60805160601c6159ed6200018e60003960008181610fa901528181610fec01528181611bd601528181611c190152611d5101526159ed6000f3fe608060405260043610620003b75760003560e01c806362b83dda11620001eb578063ac353626116200010b578063d7ec3baa11620000a1578063ef43bd631162000078578063ef43bd631462000b15578063f0f442601462000b2f578063f2fde38b1462000b54578063fd0f0d301462000b7957600080fd5b8063d7ec3baa1462000ab3578063dd4670641462000ad8578063e6aa216c1462000afd57600080fd5b8063d0e30db011620000e2578063d0e30db01462000a3a578063d13892a61462000a44578063d13f90b41462000a69578063d2c13da51462000a8e57600080fd5b8063ac353626146200095e578063cbecf45514620009fd578063cc90ef5c1462000a1557600080fd5b80639094631e116200018157806398176a01116200015857806398176a0114620008e4578063a7ab69611462000909578063aa6138391462000921578063abd70aa2146200094657600080fd5b80639094631e1462000853578063926d45b914620008755780639403b63414620008aa57600080fd5b80637d29e6e611620001c25780637d29e6e614620007e157806389d855ad14620008035780638da5cb5b146200081b5780638ff5ffad146200083b57600080fd5b806362b83dda146200078c5780636c17f67e14620007a4578063715018a614620007c957600080fd5b8063441a3e7011620002d757806352d1902d116200026d5780635ab492fd11620002445780635ab492fd14620007025780635dde8895146200071e5780636083e59a146200075257806361d027b3146200076a57600080fd5b806352d1902d14620006b057806353b4b9bf14620006c857806355ad984f14620006e057600080fd5b80634eddea0611620002ae5780634eddea0614620006375780634f1ef286146200065c5780634f864df414620006735780634ff0876a146200069857600080fd5b8063441a3e7014620005ac5780634b0b912d14620005d15780634ecce45114620005f657600080fd5b806330024dfe116200034d57806337d15139116200032457806337d1513914620005335780633cd63605146200055857806341641bac146200057d57806341b3d185146200059457600080fd5b806330024dfe14620004d1578063334b312714620004f65780633659cfe6146200050e57600080fd5b8063107edda6116200038e578063107edda61462000434578063295891fd146200046f5780632966b3d614620004875780632f3ffb9f146200049f57600080fd5b806303296dac14620003c45780630cbac22a14620003ef5780630fa67db2146200041657600080fd5b36620003bf57005b600080fd5b348015620003d157600080fd5b50620003dc60d65481565b6040519081526020015b60405180910390f35b348015620003fc57600080fd5b50620004146200040e366004620040bf565b62000b91565b005b3480156200042357600080fd5b50620003dc670de0b6b3a764000081565b3480156200044157600080fd5b5060c95462000456906001600160a01b031681565b6040516001600160a01b039091168152602001620003e6565b3480156200047c57600080fd5b50620003dc60cf5481565b3480156200049457600080fd5b50620003dc60d55481565b348015620004ac57600080fd5b5060d454620004c090610100900460ff1681565b6040519015158152602001620003e6565b348015620004de57600080fd5b5062000414620004f0366004620040bf565b62000f56565b3480156200050357600080fd5b50620003dc60d85481565b3480156200051b57600080fd5b50620004146200052d36600462003ee1565b62000f9e565b3480156200054057600080fd5b5062000414620005523660046200400f565b6200108a565b3480156200056557600080fd5b506200041462000577366004620040bf565b6200113d565b3480156200058a57600080fd5b5060d954620003dc565b348015620005a157600080fd5b50620003dc60d25481565b348015620005b957600080fd5b5062000414620005cb36600462004101565b6200130f565b348015620005de57600080fd5b50620003dc620005f0366004620040d9565b620016d3565b3480156200060357600080fd5b506200061b62000615366004620040bf565b620017c7565b60408051938452602084019290925290820152606001620003e6565b3480156200064457600080fd5b50620004146200065636600462004101565b62001b77565b620004146200066d36600462003f3f565b62001bcb565b3480156200068057600080fd5b50620004146200069236600462004149565b62001ca8565b348015620006a557600080fd5b50620003dc60d05481565b348015620006bd57600080fd5b50620003dc62001d44565b348015620006d557600080fd5b50620003dc62001dfa565b348015620006ed57600080fd5b5060d454620004c09062010000900460ff1681565b3480156200070f57600080fd5b5060d454620004c09060ff1681565b3480156200072b57600080fd5b50620007436200073d366004620040bf565b62001f97565b604051620003e69190620041f0565b3480156200075f57600080fd5b50620003dc60d35481565b3480156200077757600080fd5b5060cc5462000456906001600160a01b031681565b3480156200079957600080fd5b506200041462002027565b348015620007b157600080fd5b5062000414620007c336600462003f01565b620021dd565b348015620007d657600080fd5b506200041462002287565b348015620007ee57600080fd5b5060cb5462000456906001600160a01b031681565b3480156200081057600080fd5b50620003dc60ce5481565b3480156200082857600080fd5b506033546001600160a01b031662000456565b3480156200084857600080fd5b50620003dc60d75481565b3480156200086057600080fd5b5060ca5462000456906001600160a01b031681565b3480156200088257600080fd5b506200089a62000894366004620040bf565b6200229f565b604051620003e692919062004205565b348015620008b757600080fd5b5062000456620008c9366004620040bf565b600090815260da60205260409020546001600160a01b031690565b348015620008f157600080fd5b506200041462000903366004620040bf565b62002535565b3480156200091657600080fd5b50620003dc60d15481565b3480156200092e57600080fd5b506200045662000940366004620040bf565b6200258c565b3480156200095357600080fd5b50620003dc620025bf565b3480156200096b57600080fd5b50620009c46200097d366004620040bf565b60db6020526000908152604090206001810154600282015460038301546004840154600590940154929391929091906001600160a01b03811690600160a01b900460ff1686565b6040805196875260208701959095529385019290925260608401526001600160a01b03166080830152151560a082015260c001620003e6565b34801562000a0a57600080fd5b50620003dc60cd5481565b34801562000a2257600080fd5b506200041462000a343660046200400f565b620025d6565b620004146200267b565b34801562000a5157600080fd5b506200041462000a633660046200400f565b6200278f565b34801562000a7657600080fd5b506200041462000a8836600462004069565b62002845565b34801562000a9b57600080fd5b506200041462000aad366004620040bf565b620029c9565b34801562000ac057600080fd5b506200041462000ad236600462003ee1565b62002a0b565b34801562000ae557600080fd5b506200041462000af7366004620040bf565b62002a66565b34801562000b0a57600080fd5b50620003dc62002c2c565b34801562000b2257600080fd5b50620003dc6301e1338081565b34801562000b3c57600080fd5b506200041462000b4e36600462003ee1565b62002d18565b34801562000b6157600080fd5b506200041462000b7336600462003ee1565b62002d90565b34801562000b8657600080fd5b50620003dc62002e0c565b60d45462010000900460ff161562000bf05760405162461bcd60e51b815260206004820152601b60248201527f4552525f544849535f46554e4354494f4e5f49535f504155534544000000000060448201526064015b60405180910390fd5b600081815260da60205260409020546001600160a01b03168062000c4b5760405162461bcd60e51b815260206004820152601160248201527008aa4a4be929cac82989288be929c888ab607b1b604482015260640162000be7565b6000816001600160a01b031663fb7795936040518163ffffffff1660e01b815260040160206040518083038186803b15801562000c8757600080fd5b505afa15801562000c9c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000cc291906200404f565b60ca5460405163cfdbb7cd60e01b81526001600160a01b0385811660048301526024820184905292935091169063cfdbb7cd9060440160206040518083038186803b15801562000d1157600080fd5b505afa15801562000d26573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d4c91906200402f565b1562000d9b5760405162461bcd60e51b815260206004820152601460248201527f4552525f4e4f545f554e4c4f434b45445f594554000000000000000000000000604482015260640162000be7565b60ca5460405163cfd4766360e01b81526001600160a01b0384811660048301819052602483018590529263634b91e3926000929091169063cfd476639060440160206040518083038186803b15801562000df457600080fd5b505afa15801562000e09573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e2f91906200404f565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801562000e6e57600080fd5b505af115801562000e83573d6000803e3d6000fd5b5050505062000e928262002e41565b5060d98054600181019091557fcc6782fd46dd71c5f512301ab049782450b4eaf79fdac5443d93d274d39167860180546001600160a01b0384166001600160a01b031991821617909155600084815260da602052604090208054909116905562000f0160d68054600019019055565b60d9546001600160a01b038316907ffc99b3f1fba19a9b8893bbecdfe74cda0b7d9a022da5532968f0965acaec76629062000f3f9060019062004395565b6040519081526020015b60405180910390a2505050565b62000f6062002ea6565b60d081905560405181815233907f6adf2e595caf10dfb9380726d5970ffae7c17d8ee29cfa070f120611fd6b37f8906020015b60405180910390a250565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016141562000fea5760405162461bcd60e51b815260040162000be7906200425e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166200103560008051602062005971833981519152546001600160a01b031690565b6001600160a01b0316146200105e5760405162461bcd60e51b815260040162000be790620042aa565b620010698162002f02565b60408051600080825260208201909252620010879183919062002f0c565b50565b6200109462002ea6565b60d45460ff6101009091041615158115151415620010f15760405162461bcd60e51b81526020600482015260196024820152784552525f414c52454144595f444553495245445f56414c554560381b604482015260640162000be7565b60d480548215156101000261ff001990911617905560405133907f7f3e782c9a180a7e1f7b241e6ba82444cd86b213d8a11275f56615ab035602d49062000f9390841515815260200190565b60d45462010000900460ff1615620011985760405162461bcd60e51b815260206004820152601b60248201527f4552525f544849535f46554e4354494f4e5f49535f5041555345440000000000604482015260640162000be7565b600060d98281548110620011b057620011b062004437565b6000918252602090912001546001600160a01b03169050806200120a5760405162461bcd60e51b815260206004820152601160248201527008aa4a4be929cac82989288be929c888ab607b1b604482015260640162000be7565b60d980546200121c9060019062004395565b815481106200122f576200122f62004437565b60009182526020909120015460d980546001600160a01b0390921691849081106200125e576200125e62004437565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060d9805480620012a057620012a062004421565b6001900381819060005260206000200160006101000a8154906001600160a01b0302191690559055620012d7816000600162003094565b6040516001600160a01b038216907f782f50839991e1945032ed00da77e4465b5a83ce870ec84c9bb87e62a1a5c0a690600090a25050565b60d454610100900460ff1615620013695760405162461bcd60e51b815260206004820152601660248201527f4552525f57495448445241575f49535f50415553454400000000000000000000604482015260640162000be7565b600082815260db602052604090206001810154620013bd5760405162461bcd60e51b815260206004820152601060248201526f11549497d5d4925117d253959053125160821b604482015260640162000be7565b60d1548160010154620013d1919062004341565b421015620014225760405162461bcd60e51b815260206004820152601a60248201527f4552525f4e4f545f454e4f5547485f54494d455f504153534544000000000000604482015260640162000be7565b6005810154600160a01b900460ff1615620014805760405162461bcd60e51b815260206004820152601560248201527f4552525f414c52454144595f57495448445241574e0000000000000000000000604482015260640162000be7565b60058101805460ff60a01b198116600160a01b179091556001600160a01b0316338114620014e45760405162461bcd60e51b815260206004820152601060248201526f11549497d5539055551213d49256915160821b604482015260640162000be7565b60028201548015620014fb57620014fb81620030fe565b60038301541562001602578254600090600147835b83811015620015b35782838a16146200159b57620015618860000182815481106200153f576200153f62004437565b600091825260208220600390910201546001600160a01b0316908c9062003094565b87600001818154811062001579576200157962004437565b9060005260206000209060030201600201548562001598919062004341565b94505b620015a860028462004373565b925060010162001510565b508660030154848860040154620015cb919062004373565b620015d791906200435c565b620015e3824762004395565b620015ef919062004395565b620015fb908662004341565b9450505050505b60008111620016485760405162461bcd60e51b815260206004820152601160248201527011549497d19553131657d4d31054d21151607a1b604482015260640162000be7565b6040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156200167f573d6000803e3d6000fd5b5060408051868152602081018390529081018590526001600160a01b038316907fd52551477a320999cde57bfa527233cd7a79f23cd5c9a1d73b20ca2dac999aa69060600160405180910390a25050505050565b600080620016e062001dfa565b9050600060c960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200173357600080fd5b505afa15801562001748573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200176e91906200404f565b90508315620017865762001783858362004395565b91505b81158062001792575080155b15620017a3578492505050620017c1565b81620017b0828762004373565b620017bc91906200435c565b925050505b92915050565b600080600080670de0b6b3a7640000620017e062002c2c565b620017ec908762004373565b620017f891906200435c565b9050600062001806620025bf565b905080821162001820575092506000915081905062001b70565b60cf546000908190815b8181101562001b3557600081815260da60205260409020546001600160a01b0316801562001b2b576000816001600160a01b031663fb7795936040518163ffffffff1660e01b815260040160206040518083038186803b1580156200188e57600080fd5b505afa158015620018a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c991906200404f565b60ca5460405163cfd4766360e01b81526001600160a01b0385811660048301526024820184905292935091169063cfd476639060440160206040518083038186803b1580156200191857600080fd5b505afa1580156200192d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200195391906200404f565b6200195f908762004341565b60ca5460405163cfdbb7cd60e01b81526001600160a01b0385811660048301526024820185905292985091169063cfdbb7cd9060440160206040518083038186803b158015620019ae57600080fd5b505afa158015620019c3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019e991906200402f565b1562001b29576000826001600160a01b0316632b1931fe6040518163ffffffff1660e01b815260040160206040518083038186803b15801562001a2b57600080fd5b505afa15801562001a40573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a6691906200404f565b60ca54604051635fb45b5360e01b81526001600160a01b039182166004820152908516602482015260448101849052606481018290526084810182905290915073__$5d081bb259322a68472281687e69aa3f61$__90635fb45b539060a40160206040518083038186803b15801562001ade57600080fd5b505af415801562001af3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b1991906200404f565b62001b25908762004341565b9550505b505b506001016200182a565b50600062001b44858762004395565b905060008462001b55858462004373565b62001b6191906200435c565b96995090975094955050505050505b9193909250565b62001b8162002ea6565b60d282905560d3819055604080518381526020810183905233917f6336de44e69f674663e4ef431d96ff47327224598c485ce7dd1c486ba216db1791015b60405180910390a25050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016141562001c175760405162461bcd60e51b815260040162000be7906200425e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031662001c6260008051602062005971833981519152546001600160a01b031690565b6001600160a01b03161462001c8b5760405162461bcd60e51b815260040162000be790620042aa565b62001c968262002f02565b62001ca48282600162002f0c565b5050565b60d45460ff161562001cfd5760405162461bcd60e51b815260206004820152601860248201527f4552525f554e44454c45474154455f49535f5041555345440000000000000000604482015260640162000be7565b62001d0b338484846200311a565b604080518481526020810184905233917f0eb3707116738c7f5ecbd2c2ee16e61ef2f6cf835efff5fb328938561486a2e4910162000f49565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161462001de65760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840162000be7565b506000805160206200597183398151915290565b60008062001e07620025bf565b60cf5490915060005b8181101562001ec657600081815260da60205260409020546001600160a01b0316801562001ebc57806001600160a01b031663646ce0106040518163ffffffff1660e01b815260040160206040518083038186803b15801562001e7257600080fd5b505afa15801562001e87573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ead91906200404f565b62001eb9908562004341565b93505b5060010162001e10565b5060d95460005b8181101562001f8e57600060d9828154811062001eee5762001eee62004437565b6000918252602091829020015460408051630646ce0160e41b815290516001600160a01b039092169350839263646ce01092600480840193829003018186803b15801562001f3b57600080fd5b505afa15801562001f50573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001f7691906200404f565b62001f82908662004341565b94505060010162001ecd565b50919392505050565b600081815260db60209081526040808320805482518185028101850190935280835260609492939192909184015b828210156200201c576000848152602090819020604080516060810182526003860290920180546001600160a01b031683526001808201548486015260029091015491830191909152908352909201910162001fc5565b505050509050919050565b60d45462010000900460ff1615620020825760405162461bcd60e51b815260206004820152601b60248201527f4552525f544849535f46554e4354494f4e5f49535f5041555345440000000000604482015260640162000be7565b60ca5460408051630ecce30160e31b815290516000926001600160a01b0316916376671808916004808301926020929190829003018186803b158015620020c857600080fd5b505afa158015620020dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200210391906200404f565b905060ce548111620021125750565b60ce81905560cf54479060005b818110156200215e57600081815260da60205260409020546001600160a01b031680156200215457620021528162002e41565b505b506001016200211f565b5060cd5415620021d85760cd5447906000906127109062002180868562004395565b6200218c919062004373565b6200219891906200435c565b60cc546040519192506001600160a01b03169082156108fc029083906000818181858888f19350505050158015620021d4573d6000803e3d6000fd5b5050505b505050565b620021e762002ea6565b60405163880cdc3160e01b81526001600160a01b03828116600483015283169063880cdc3190602401600060405180830381600087803b1580156200222b57600080fd5b505af115801562002240573d6000803e3d6000fd5b5050604080516001600160a01b038681168252851660208201523393507f613a5b1d714fb5a78efb4fba0430702fa82a9e37b373f195d4d4b7dcb4b970c892500162001bbf565b6200229162002ea6565b6200229d600062003611565b565b60cf54606090600090818167ffffffffffffffff811115620022c557620022c56200444d565b6040519080825280602002602001820160405280156200232657816020015b62002312604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b815260200190600190039081620022e45790505b5060d5549091506000805b8715620024495762002344838662003663565b600081815260da60205260409020549093506001600160a01b0316806200236c575062002449565b60008060006200237d848d62003693565b9250925092508388878151811062002399576200239962004437565b6020026020010151600001906001600160a01b031690816001600160a01b03168152505082888781518110620023d357620023d362004437565b6020026020010151602001818152505081888781518110620023f957620023f962004437565b60209081029190910101516040015262002414828462004395565b62002420908662004341565b94506200242e818d62004395565b9b506200243d60018762004341565b95505050505062002331565b60008267ffffffffffffffff8111156200246757620024676200444d565b604051908082528060200260200182016040528015620024c857816020015b620024b4604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b815260200190600190039081620024865790505b50905060005b838110156200252757858181518110620024ec57620024ec62004437565b602002602001015182828151811062002509576200250962004437565b60200260200101819052506200251f8160010190565b9050620024ce565b509890975095505050505050565b6200253f62002ea6565b612710811115620025875760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f56414c554560781b604482015260640162000be7565b60cd55565b600060d98281548110620025a457620025a462004437565b6000918252602090912001546001600160a01b031692915050565b600060d85447620025d1919062004395565b905090565b620025e062002ea6565b60d45460ff1615158115151415620026375760405162461bcd60e51b81526020600482015260196024820152784552525f414c52454144595f444553495245445f56414c554560381b604482015260640162000be7565b60d4805460ff191682151590811790915560405190815233907fd009bec484226a9cd47773e930e5c5ba25d927bd3422e7fe83dbd8c3dfefa0f39060200162000f93565b60d2543490811080159062002692575060d3548111155b620026e05760405162461bcd60e51b815260206004820152601960248201527f4552525f414d4f554e545f4f5554534944455f4c494d49545300000000000000604482015260640162000be7565b6000620026ef826001620016d3565b60c9546040516340c10f1960e01b8152336004820152602481018390529192506001600160a01b0316906340c10f1990604401600060405180830381600087803b1580156200273d57600080fd5b505af115801562002752573d6000803e3d6000fd5b505060408051348152602081018590523393507f8de097f054bf5282188a61136aa10aff99a4a5ad0ca0985010a52dbc83f8bfd592500162001bbf565b6200279962002ea6565b60d45460ff620100009091041615158115151415620027f75760405162461bcd60e51b81526020600482015260196024820152784552525f414c52454144595f444553495245445f56414c554560381b604482015260640162000be7565b60d48054821515620100000262ff00001990911617905560405133907f1a480001006251004b925e05a0c5f3c8cbc7630eee9e6cdc45a865fa3fd9334f9062000f9390841515815260200190565b600054610100900460ff1615808015620028665750600054600160ff909116105b80620028825750303b15801562002882575060005460ff166001145b620028e75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000be7565b6000805460ff1916600117905580156200290b576000805461ff0019166101001790555b6200291562003957565b6200291f6200398b565b60c980546001600160a01b038089166001600160a01b03199283161790925560ca80549288169282169290921790915560cf85905560d084905560d183905560cc805490911633179055600060d25568056bc75e2d6310000060d3558015620021d4576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050505050565b620029d362002ea6565b60d181905560405181815233907f36ac5862acb8a66c4b3141acc98a2d72ffc2e0f05045a1bf1709a2acea66dbd79060200162000f93565b62002a1562002ea6565b60cb80546001600160a01b0319166001600160a01b03831690811790915560405190815233907f49f7c39d3a1550780f0253120b78fb960ba7c07494f86aa7cc30299b00a8374a9060200162000f93565b62002a7062002ea6565b60d75442101562002ac45760405162461bcd60e51b815260206004820152601760248201527f4552525f574149545f464f525f4e4558545f45504f4348000000000000000000604482015260640162000be7565b60008111801562002ade575062002ada620025bf565b8111155b62002b215760405162461bcd60e51b815260206004820152601260248201527111549497d253959053125117d05353d5539560721b604482015260640162000be7565b60d05460d7600082825462002b37919062004341565b909155505060cb54604051631bf02e6b60e11b81526004810183905260009182916001600160a01b03909116906337e05cd6906024016040805180830381600087803b15801562002b8757600080fd5b505af115801562002b9c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002bc2919062004124565b91509150600062002bd383620039b5565b905062002be281838662003aa4565b60408051838152602081018690526001600160a01b038316917f22af55bbeeb3fac1ac53cea63fa630fadfb2eb7a5815b44870d84d8ee437d5bd910160405180910390a250505050565b60008062002c3962001dfa565b9050600060c960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562002c8c57600080fd5b505afa15801562002ca1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002cc791906200404f565b905081158062002cd5575080155b1562002cf75762002cf0670de0b6b3a7640000600162004373565b9250505090565b8062002d0c670de0b6b3a76400008462004373565b62002cf091906200435c565b62002d2262002ea6565b6001600160a01b03811662002d6e5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f56414c554560781b604482015260640162000be7565b60cc80546001600160a01b0319166001600160a01b0392909216919091179055565b62002d9a62002ea6565b6001600160a01b03811662002e015760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000be7565b620010878162003611565b606462002e23670de0b6b3a7640000601e62004373565b62002e2f91906200435c565b81565b6001600160a01b03163b151590565b6000816001600160a01b031663372500ab6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562002e7f57600080fd5b505af192505050801562002e91575060015b62002e9e57506000919050565b506001919050565b6033546001600160a01b031633146200229d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000be7565b6200108762002ea6565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161562002f4257620021d88362003b30565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b815260040160206040518083038186803b15801562002f7c57600080fd5b505afa92505050801562002faf575060408051601f3d908101601f1916820190925262002fac918101906200404f565b60015b620030145760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840162000be7565b600080516020620059718339815191528114620030865760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840162000be7565b50620021d883838362003bcf565b604051631c683a1b60e11b81526004810183905281151560248201526001600160a01b038416906338d07436906044015b600060405180830381600087803b158015620030e057600080fd5b505af1158015620030f5573d6000803e3d6000fd5b50505050505050565b8060d8600082825462003112919062004395565b909155505050565b600082116200315e5760405162461bcd60e51b815260206004820152600f60248201526e11549497d6915493d7d05353d55395608a1b604482015260640162000be7565b60008311620031b05760405162461bcd60e51b815260206004820152601960248201527f4552525f777249445f4d5553545f42455f4e4f4e5f5a45524f00000000000000604482015260640162000be7565b600083815260db60205260409020600181015415620032125760405162461bcd60e51b815260206004820152601560248201527f4552525f575249445f414c52454144595f555345440000000000000000000000604482015260640162000be7565b4260018201556005810180546001600160a01b0319166001600160a01b038716179055600080806200324486620017c7565b919450925090508462003258828562004395565b1015620032a85760405162461bcd60e51b815260206004820152601b60248201527f4552525f494e53554646494349454e545f414d4f554e545f4f55540000000000604482015260640162000be7565b60c95460405163079cc67960e41b81526001600160a01b038a8116600483015260248201899052909116906379cc679090604401600060405180830381600087803b158015620032f757600080fd5b505af11580156200330c573d6000803e3d6000fd5b5050505081600014156200333257620033258362003c00565b6002840183905562003607565b6200334862003342838562004395565b62003c00565b60008062003356846200229f565b815160cf5460d5549395509193509160005b83811015620035ca57620033df8682815181106200338a576200338a62004437565b6020026020010151600001518e888481518110620033ac57620033ac62004437565b602002602001015160200151898581518110620033cd57620033cd62004437565b60200260200101516040015162003c14565b620033ec60018562004395565b811080620034a357506200340260018562004395565b81148015620034a3575085818151811062003421576200342162004437565b6020026020010151600001516001600160a01b0316632b1931fe6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200346657600080fd5b505afa1580156200347b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620034a191906200404f565b155b15620034ed57620034b5828462003663565b600081815260da6020526040902080546001600160a01b03191690559150620034dd62003ccf565b620034ed60d68054600019019055565b89600001604051806060016040528088848151811062003511576200351162004437565b6020026020010151600001516001600160a01b0316815260200188848151811062003540576200354062004437565b602002602001015160200151815260200188848151811062003566576200356662004437565b602090810291909101810151604090810151909252835460018082018655600095865294829020845160039092020180546001600160a01b0319166001600160a01b0390921691909117815590830151818501559101516002909101550162003368565b50620035d7878962004395565b60028a01556003890187905585841115620035f0578593505b620035fc848762004395565b60048a015550505050505b5050505050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081600162003674828662004341565b62003680919062004395565b6200368c9190620043de565b9392505050565b600080600080856001600160a01b031663fb7795936040518163ffffffff1660e01b815260040160206040518083038186803b158015620036d357600080fd5b505afa158015620036e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200370e91906200404f565b90506000866001600160a01b0316632b1931fe6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200374c57600080fd5b505afa15801562003761573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200378791906200404f565b60ca54604051635fb45b5360e01b81526001600160a01b039182166004820152908916602482015260448101849052606481018290526084810182905290915060009073__$5d081bb259322a68472281687e69aa3f61$__90635fb45b539060a40160206040518083038186803b1580156200380257600080fd5b505af415801562003817573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200383d91906200404f565b62003849908362004395565b905086811115620039465760008162003863848a62004373565b6200386f91906200435c565b60ca54604051635fb45b5360e01b81526001600160a01b039182166004820152908b16602482015260448101869052606481018290526084810185905290915060009073__$5d081bb259322a68472281687e69aa3f61$__90635fb45b539060a40160206040518083038186803b158015620038ea57600080fd5b505af4158015620038ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200392591906200404f565b90508162003934828262004395565b8a975097509750505050505062003950565b9094509250829150505b9250925092565b600054610100900460ff16620039815760405162461bcd60e51b815260040162000be790620042f6565b6200229d62003ce4565b600054610100900460ff166200229d5760405162461bcd60e51b815260040162000be790620042f6565b600060cf5460d6541062003a0c5760405162461bcd60e51b815260206004820152601760248201527f4552525f4d41585f5641554c54535f4f43435550494544000000000000000000604482015260640162000be7565b60ca546040516000916001600160a01b031690849062003a2c9062003ed3565b6001600160a01b0390921682526020820152604001604051809103906000f08015801562003a5e573d6000803e3d6000fd5b5060d554600090815260da6020526040902080546001600160a01b0319166001600160a01b038316179055905062003a9562003d19565b620017c160d680546001019055565b826001600160a01b031663c89e4361826040518263ffffffff1660e01b81526004016000604051808303818588803b15801562003ae057600080fd5b505af115801562003af5573d6000803e3d6000fd5b505060405163a97aeed560e01b815260048101869052602481018590526001600160a01b038716935063a97aeed592506044019050620030c5565b6001600160a01b0381163b62003b9f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000be7565b6000805160206200597183398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b62003bda8362003d29565b60008251118062003be85750805b15620021d85762003bfa838362003d6b565b50505050565b8060d8600082825462003112919062004341565b604051636198e33960e01b8152600481018390526001600160a01b03851690636198e33990602401600060405180830381600087803b15801562003c5757600080fd5b505af115801562003c6c573d6000803e3d6000fd5b505060405163634b91e360e01b815260048101869052602481018490526001600160a01b038716925063634b91e39150604401600060405180830381600087803b15801562003cba57600080fd5b505af115801562003607573d6000803e3d6000fd5b62003cdf60d55460cf5462003663565b60d555565b600054610100900460ff1662003d0e5760405162461bcd60e51b815260040162000be790620042f6565b6200229d3362003611565b62003cdf60d55460cf5462003d93565b62003d348162003b30565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200368c8383604051806060016040528060278152602001620059916027913962003da3565b6000816200368084600162004341565b6060600080856001600160a01b03168560405162003dc29190620041d2565b600060405180830381855af49150503d806000811462003dff576040519150601f19603f3d011682016040523d82523d6000602084013e62003e04565b606091505b509150915062003e178683838762003e21565b9695505050505050565b6060831562003e9257825162003e8a576001600160a01b0385163b62003e8a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000be7565b508162003e9e565b62003e9e838362003ea6565b949350505050565b81511562003eb75781518083602001fd5b8060405162461bcd60e51b815260040162000be7919062004229565b6114e8806200448983390190565b60006020828403121562003ef457600080fd5b81356200368c8162004463565b6000806040838503121562003f1557600080fd5b823562003f228162004463565b9150602083013562003f348162004463565b809150509250929050565b6000806040838503121562003f5357600080fd5b823562003f608162004463565b9150602083013567ffffffffffffffff8082111562003f7e57600080fd5b818501915085601f83011262003f9357600080fd5b81358181111562003fa85762003fa86200444d565b604051601f8201601f19908116603f0116810190838211818310171562003fd35762003fd36200444d565b8160405282815288602084870101111562003fed57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000602082840312156200402257600080fd5b81356200368c8162004479565b6000602082840312156200404257600080fd5b81516200368c8162004479565b6000602082840312156200406257600080fd5b5051919050565b600080600080600060a086880312156200408257600080fd5b85356200408f8162004463565b94506020860135620040a18162004463565b94979496505050506040830135926060810135926080909101359150565b600060208284031215620040d257600080fd5b5035919050565b60008060408385031215620040ed57600080fd5b82359150602083013562003f348162004479565b600080604083850312156200411557600080fd5b50508035926020909101359150565b600080604083850312156200413857600080fd5b505080516020909101519092909150565b6000806000606084860312156200415f57600080fd5b505081359360208301359350604090920135919050565b600081518084526020808501945080840160005b83811015620041c757815180516001600160a01b03168852838101518489015260409081015190880152606090960195908201906001016200418a565b509495945050505050565b60008251620041e6818460208701620043af565b9190910192915050565b6020815260006200368c602083018462004176565b6040815260006200421a604083018562004176565b90508260208301529392505050565b60208152600082518060208401526200424a816040850160208701620043af565b601f01601f19169190910160400192915050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008219821115620043575762004357620043f5565b500190565b6000826200436e576200436e6200440b565b500490565b6000816000190483118215151615620043905762004390620043f5565b500290565b600082821015620043aa57620043aa620043f5565b500390565b60005b83811015620043cc578181015183820152602001620043b2565b8381111562003bfa5750506000910152565b600082620043f057620043f06200440b565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200108757600080fd5b80151581146200108757600080fdfe60e06040523480156200001157600080fd5b50604051620014e8380380620014e88339810160408190526200003491620000f9565b600080546001600160a01b031916331781556001600160601b0319606084901b1660805260c082905260405163b5d8962760e01b8152600481018390526001600160a01b0384169063b5d896279060240160e06040518083038186803b1580156200009e57600080fd5b505afa158015620000b3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d991906200012a565b60601b6001600160601b03191660a05250620001a6975050505050505050565b600080604083850312156200010d57600080fd5b82516200011a816200018d565b6020939093015192949293505050565b600080600080600080600060e0888a0312156200014657600080fd5b875196506020880151955060408801519450606088015193506080880151925060a0880151915060c08801516200017d816200018d565b8091505092959891949750929550565b6001600160a01b0381168114620001a357600080fd5b50565b60805160601c60a05160601c60c051611248620002a06000396000818161030d0152818161037f0152818161047101528181610570015281816106930152818161075801528181610846015281816108f8015281816109ba01528181610a7d01528181610b4001528181610d1501528181610db901528181610e790152610ef301526000610205015260008181610291015281816103a8015281816104970152818161059f015281816106b9015281816107850152818161087a0152818161092b015281816109ee01528181610ab701528181610b7801528181610d4901528181610ddf01528181610ead0152610f2601526112486000f3fe6080604052600436106101025760003560e01c806368d57d3f11610095578063a97aeed511610064578063a97aeed5146102b3578063c89e4361146102d3578063e0819cd4146102db578063fb779593146102fb578063ffa1ad741461032f57600080fd5b806368d57d3f146101f3578063880cdc311461023f5780638da5cb5b1461025f5780639094631e1461027f57600080fd5b80633d8527ba116100d15780633d8527ba146101895780636198e3391461019e578063634b91e3146101be578063646ce010146101de57600080fd5b80630fa67db21461010e5780632b1931fe1461013d578063372500ab1461015257806338d074361461016957600080fd5b3661010957005b600080fd5b34801561011a57600080fd5b5061012a670de0b6b3a764000081565b6040519081526020015b60405180910390f35b34801561014957600080fd5b5061012a61036a565b34801561015e57600080fd5b5061016761042f565b005b34801561017557600080fd5b5061016761018436600461107f565b610537565b34801561019557600080fd5b5061016761065a565b3480156101aa57600080fd5b506101676101b936600461104d565b61071f565b3480156101ca57600080fd5b506101676101d93660046110af565b61080d565b3480156101ea57600080fd5b5061012a6108e3565b3480156101ff57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610134565b34801561024b57600080fd5b5061016761025a366004611007565b610c39565b34801561026b57600080fd5b50600054610227906001600160a01b031681565b34801561028b57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b3480156102bf57600080fd5b506101676102ce3660046110af565b610cdc565b610167610d80565b3480156102e757600080fd5b506101676102f63660046110af565b610e40565b34801561030757600080fd5b5061012a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561033b57600080fd5b5061035d60405180604001604052806002815260200161763160f01b81525081565b60405161013491906110ff565b604051630ce0645f60e31b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063670322f89060440160206040518083038186803b1580156103f257600080fd5b505afa158015610406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042a9190611066565b905090565b6000546001600160a01b031633146104625760405162461bcd60e51b815260040161045990611154565b60405180910390fd5b604051630962ef7960e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630962ef7990602401600060405180830381600087803b1580156104e357600080fd5b505af11580156104f7573d6000803e3d6000fd5b5050600080546040516001600160a01b0390911693504780156108fc02935091818181858888f19350505050158015610534573d6000803e3d6000fd5b50565b6000546001600160a01b031633146105615760405162461bcd60e51b815260040161045990611154565b604051630441a3e760e41b81527f000000000000000000000000000000000000000000000000000000000000000060048201526024810183905247907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063441a3e7090604401600060405180830381600087803b1580156105eb57600080fd5b505af11580156105ff573d6000803e3d6000fd5b5050505060004790508261061a5761061782826111d7565b90505b600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610653573d6000803e3d6000fd5b5050505050565b6000546001600160a01b031633146106845760405162461bcd60e51b815260040161045990611154565b604051630230da1d60e21b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906308c3687490602401600060405180830381600087803b15801561070557600080fd5b505af1158015610719573d6000803e3d6000fd5b50505050565b6000546001600160a01b031633146107495760405162461bcd60e51b815260040161045990611154565b60405163074eb10b60e21b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631d3ac42c90604401602060405180830381600087803b1580156107d157600080fd5b505af11580156107e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108099190611066565b5050565b6000546001600160a01b031633146108375760405162461bcd60e51b815260040161045990611154565b6040516313e1937d60e21b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634f864df4906064015b600060405180830381600087803b1580156108c757600080fd5b505af11580156108db573d6000803e3d6000fd5b505050505050565b60405163cfd4766360e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000602482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cfd476639060440160206040518083038186803b15801561096d57600080fd5b505afa158015610981573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a59190611066565b60405163304cf65960e11b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201529091506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636099ecb29060440160206040518083038186803b158015610a3057600080fd5b505afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a689190611066565b604051630f9380a960e11b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201526000604482018190529192506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631f2701529060640160606040518083038186803b158015610af957600080fd5b505afa158015610b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3191906110d1565b6040516361ef2c0760e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152909350600092508291506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c3de580e9060240160206040518083038186803b158015610bba57600080fd5b505afa158015610bce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf29190611030565b90508015610c0f57610c0c610c07848761117e565b610ee4565b91505b8183610c1b868861117e565b610c25919061117e565b610c2f91906111d7565b9550505050505090565b6000546001600160a01b03163314610c635760405162461bcd60e51b815260040161045990611154565b6001600160a01b038116610cad5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f56414c554560781b6044820152606401610459565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610d065760405162461bcd60e51b815260040161045990611154565b60405163de67f21560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063de67f215906064016108ad565b6000546001600160a01b03163314610daa5760405162461bcd60e51b815260040161045990611154565b604051639fa6dd3560e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639fa6dd359034906024016000604051808303818588803b158015610e2c57600080fd5b505af1158015610653573d6000803e3d6000fd5b6000546001600160a01b03163314610e6a5760405162461bcd60e51b815260040161045990611154565b60405163bd14d90760e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bd14d907906064016108ad565b60405163c65ee0e160e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c65ee0e19060240160206040518083038186803b158015610f6857600080fd5b505afa158015610f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa09190611066565b9050670de0b6b3a76400008110610fba5750600092915050565b6000670de0b6b3a7640000610fcf83826111d7565b610fd990866111b8565b610fe39190611196565b610fee90600161117e565b90508381111561100057509192915050565b9392505050565b60006020828403121561101957600080fd5b81356001600160a01b038116811461100057600080fd5b60006020828403121561104257600080fd5b815161100081611204565b60006020828403121561105f57600080fd5b5035919050565b60006020828403121561107857600080fd5b5051919050565b6000806040838503121561109257600080fd5b8235915060208301356110a481611204565b809150509250929050565b600080604083850312156110c257600080fd5b50508035926020909101359150565b6000806000606084860312156110e657600080fd5b8351925060208401519150604084015190509250925092565b600060208083528351808285015260005b8181101561112c57858101830151858201604001528201611110565b8181111561113e576000604083870101525b50601f01601f1916929092016040019392505050565b60208082526010908201526f11549497d5539055551213d49256915160821b604082015260600190565b60008219821115611191576111916111ee565b500190565b6000826111b357634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156111d2576111d26111ee565b500290565b6000828210156111e9576111e96111ee565b500390565b634e487b7160e01b600052601160045260246000fd5b801515811461053457600080fdfea2646970667358221220b4bd5ef8f0e940a42d9dac8a22de871688b9cc3cc9a6aa731612b041280bdeb864736f6c63430008070033360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220377fdff03fc22d21ced4fc4368b0119db847edd7e3624e817e3409329ddca84764736f6c63430008070033", + "deployedBytecode": "0x608060405260043610620003b75760003560e01c806362b83dda11620001eb578063ac353626116200010b578063d7ec3baa11620000a1578063ef43bd631162000078578063ef43bd631462000b15578063f0f442601462000b2f578063f2fde38b1462000b54578063fd0f0d301462000b7957600080fd5b8063d7ec3baa1462000ab3578063dd4670641462000ad8578063e6aa216c1462000afd57600080fd5b8063d0e30db011620000e2578063d0e30db01462000a3a578063d13892a61462000a44578063d13f90b41462000a69578063d2c13da51462000a8e57600080fd5b8063ac353626146200095e578063cbecf45514620009fd578063cc90ef5c1462000a1557600080fd5b80639094631e116200018157806398176a01116200015857806398176a0114620008e4578063a7ab69611462000909578063aa6138391462000921578063abd70aa2146200094657600080fd5b80639094631e1462000853578063926d45b914620008755780639403b63414620008aa57600080fd5b80637d29e6e611620001c25780637d29e6e614620007e157806389d855ad14620008035780638da5cb5b146200081b5780638ff5ffad146200083b57600080fd5b806362b83dda146200078c5780636c17f67e14620007a4578063715018a614620007c957600080fd5b8063441a3e7011620002d757806352d1902d116200026d5780635ab492fd11620002445780635ab492fd14620007025780635dde8895146200071e5780636083e59a146200075257806361d027b3146200076a57600080fd5b806352d1902d14620006b057806353b4b9bf14620006c857806355ad984f14620006e057600080fd5b80634eddea0611620002ae5780634eddea0614620006375780634f1ef286146200065c5780634f864df414620006735780634ff0876a146200069857600080fd5b8063441a3e7014620005ac5780634b0b912d14620005d15780634ecce45114620005f657600080fd5b806330024dfe116200034d57806337d15139116200032457806337d1513914620005335780633cd63605146200055857806341641bac146200057d57806341b3d185146200059457600080fd5b806330024dfe14620004d1578063334b312714620004f65780633659cfe6146200050e57600080fd5b8063107edda6116200038e578063107edda61462000434578063295891fd146200046f5780632966b3d614620004875780632f3ffb9f146200049f57600080fd5b806303296dac14620003c45780630cbac22a14620003ef5780630fa67db2146200041657600080fd5b36620003bf57005b600080fd5b348015620003d157600080fd5b50620003dc60d65481565b6040519081526020015b60405180910390f35b348015620003fc57600080fd5b50620004146200040e366004620040bf565b62000b91565b005b3480156200042357600080fd5b50620003dc670de0b6b3a764000081565b3480156200044157600080fd5b5060c95462000456906001600160a01b031681565b6040516001600160a01b039091168152602001620003e6565b3480156200047c57600080fd5b50620003dc60cf5481565b3480156200049457600080fd5b50620003dc60d55481565b348015620004ac57600080fd5b5060d454620004c090610100900460ff1681565b6040519015158152602001620003e6565b348015620004de57600080fd5b5062000414620004f0366004620040bf565b62000f56565b3480156200050357600080fd5b50620003dc60d85481565b3480156200051b57600080fd5b50620004146200052d36600462003ee1565b62000f9e565b3480156200054057600080fd5b5062000414620005523660046200400f565b6200108a565b3480156200056557600080fd5b506200041462000577366004620040bf565b6200113d565b3480156200058a57600080fd5b5060d954620003dc565b348015620005a157600080fd5b50620003dc60d25481565b348015620005b957600080fd5b5062000414620005cb36600462004101565b6200130f565b348015620005de57600080fd5b50620003dc620005f0366004620040d9565b620016d3565b3480156200060357600080fd5b506200061b62000615366004620040bf565b620017c7565b60408051938452602084019290925290820152606001620003e6565b3480156200064457600080fd5b50620004146200065636600462004101565b62001b77565b620004146200066d36600462003f3f565b62001bcb565b3480156200068057600080fd5b50620004146200069236600462004149565b62001ca8565b348015620006a557600080fd5b50620003dc60d05481565b348015620006bd57600080fd5b50620003dc62001d44565b348015620006d557600080fd5b50620003dc62001dfa565b348015620006ed57600080fd5b5060d454620004c09062010000900460ff1681565b3480156200070f57600080fd5b5060d454620004c09060ff1681565b3480156200072b57600080fd5b50620007436200073d366004620040bf565b62001f97565b604051620003e69190620041f0565b3480156200075f57600080fd5b50620003dc60d35481565b3480156200077757600080fd5b5060cc5462000456906001600160a01b031681565b3480156200079957600080fd5b506200041462002027565b348015620007b157600080fd5b5062000414620007c336600462003f01565b620021dd565b348015620007d657600080fd5b506200041462002287565b348015620007ee57600080fd5b5060cb5462000456906001600160a01b031681565b3480156200081057600080fd5b50620003dc60ce5481565b3480156200082857600080fd5b506033546001600160a01b031662000456565b3480156200084857600080fd5b50620003dc60d75481565b3480156200086057600080fd5b5060ca5462000456906001600160a01b031681565b3480156200088257600080fd5b506200089a62000894366004620040bf565b6200229f565b604051620003e692919062004205565b348015620008b757600080fd5b5062000456620008c9366004620040bf565b600090815260da60205260409020546001600160a01b031690565b348015620008f157600080fd5b506200041462000903366004620040bf565b62002535565b3480156200091657600080fd5b50620003dc60d15481565b3480156200092e57600080fd5b506200045662000940366004620040bf565b6200258c565b3480156200095357600080fd5b50620003dc620025bf565b3480156200096b57600080fd5b50620009c46200097d366004620040bf565b60db6020526000908152604090206001810154600282015460038301546004840154600590940154929391929091906001600160a01b03811690600160a01b900460ff1686565b6040805196875260208701959095529385019290925260608401526001600160a01b03166080830152151560a082015260c001620003e6565b34801562000a0a57600080fd5b50620003dc60cd5481565b34801562000a2257600080fd5b506200041462000a343660046200400f565b620025d6565b620004146200267b565b34801562000a5157600080fd5b506200041462000a633660046200400f565b6200278f565b34801562000a7657600080fd5b506200041462000a8836600462004069565b62002845565b34801562000a9b57600080fd5b506200041462000aad366004620040bf565b620029c9565b34801562000ac057600080fd5b506200041462000ad236600462003ee1565b62002a0b565b34801562000ae557600080fd5b506200041462000af7366004620040bf565b62002a66565b34801562000b0a57600080fd5b50620003dc62002c2c565b34801562000b2257600080fd5b50620003dc6301e1338081565b34801562000b3c57600080fd5b506200041462000b4e36600462003ee1565b62002d18565b34801562000b6157600080fd5b506200041462000b7336600462003ee1565b62002d90565b34801562000b8657600080fd5b50620003dc62002e0c565b60d45462010000900460ff161562000bf05760405162461bcd60e51b815260206004820152601b60248201527f4552525f544849535f46554e4354494f4e5f49535f504155534544000000000060448201526064015b60405180910390fd5b600081815260da60205260409020546001600160a01b03168062000c4b5760405162461bcd60e51b815260206004820152601160248201527008aa4a4be929cac82989288be929c888ab607b1b604482015260640162000be7565b6000816001600160a01b031663fb7795936040518163ffffffff1660e01b815260040160206040518083038186803b15801562000c8757600080fd5b505afa15801562000c9c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000cc291906200404f565b60ca5460405163cfdbb7cd60e01b81526001600160a01b0385811660048301526024820184905292935091169063cfdbb7cd9060440160206040518083038186803b15801562000d1157600080fd5b505afa15801562000d26573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d4c91906200402f565b1562000d9b5760405162461bcd60e51b815260206004820152601460248201527f4552525f4e4f545f554e4c4f434b45445f594554000000000000000000000000604482015260640162000be7565b60ca5460405163cfd4766360e01b81526001600160a01b0384811660048301819052602483018590529263634b91e3926000929091169063cfd476639060440160206040518083038186803b15801562000df457600080fd5b505afa15801562000e09573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e2f91906200404f565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801562000e6e57600080fd5b505af115801562000e83573d6000803e3d6000fd5b5050505062000e928262002e41565b5060d98054600181019091557fcc6782fd46dd71c5f512301ab049782450b4eaf79fdac5443d93d274d39167860180546001600160a01b0384166001600160a01b031991821617909155600084815260da602052604090208054909116905562000f0160d68054600019019055565b60d9546001600160a01b038316907ffc99b3f1fba19a9b8893bbecdfe74cda0b7d9a022da5532968f0965acaec76629062000f3f9060019062004395565b6040519081526020015b60405180910390a2505050565b62000f6062002ea6565b60d081905560405181815233907f6adf2e595caf10dfb9380726d5970ffae7c17d8ee29cfa070f120611fd6b37f8906020015b60405180910390a250565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016141562000fea5760405162461bcd60e51b815260040162000be7906200425e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166200103560008051602062005971833981519152546001600160a01b031690565b6001600160a01b0316146200105e5760405162461bcd60e51b815260040162000be790620042aa565b620010698162002f02565b60408051600080825260208201909252620010879183919062002f0c565b50565b6200109462002ea6565b60d45460ff6101009091041615158115151415620010f15760405162461bcd60e51b81526020600482015260196024820152784552525f414c52454144595f444553495245445f56414c554560381b604482015260640162000be7565b60d480548215156101000261ff001990911617905560405133907f7f3e782c9a180a7e1f7b241e6ba82444cd86b213d8a11275f56615ab035602d49062000f9390841515815260200190565b60d45462010000900460ff1615620011985760405162461bcd60e51b815260206004820152601b60248201527f4552525f544849535f46554e4354494f4e5f49535f5041555345440000000000604482015260640162000be7565b600060d98281548110620011b057620011b062004437565b6000918252602090912001546001600160a01b03169050806200120a5760405162461bcd60e51b815260206004820152601160248201527008aa4a4be929cac82989288be929c888ab607b1b604482015260640162000be7565b60d980546200121c9060019062004395565b815481106200122f576200122f62004437565b60009182526020909120015460d980546001600160a01b0390921691849081106200125e576200125e62004437565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060d9805480620012a057620012a062004421565b6001900381819060005260206000200160006101000a8154906001600160a01b0302191690559055620012d7816000600162003094565b6040516001600160a01b038216907f782f50839991e1945032ed00da77e4465b5a83ce870ec84c9bb87e62a1a5c0a690600090a25050565b60d454610100900460ff1615620013695760405162461bcd60e51b815260206004820152601660248201527f4552525f57495448445241575f49535f50415553454400000000000000000000604482015260640162000be7565b600082815260db602052604090206001810154620013bd5760405162461bcd60e51b815260206004820152601060248201526f11549497d5d4925117d253959053125160821b604482015260640162000be7565b60d1548160010154620013d1919062004341565b421015620014225760405162461bcd60e51b815260206004820152601a60248201527f4552525f4e4f545f454e4f5547485f54494d455f504153534544000000000000604482015260640162000be7565b6005810154600160a01b900460ff1615620014805760405162461bcd60e51b815260206004820152601560248201527f4552525f414c52454144595f57495448445241574e0000000000000000000000604482015260640162000be7565b60058101805460ff60a01b198116600160a01b179091556001600160a01b0316338114620014e45760405162461bcd60e51b815260206004820152601060248201526f11549497d5539055551213d49256915160821b604482015260640162000be7565b60028201548015620014fb57620014fb81620030fe565b60038301541562001602578254600090600147835b83811015620015b35782838a16146200159b57620015618860000182815481106200153f576200153f62004437565b600091825260208220600390910201546001600160a01b0316908c9062003094565b87600001818154811062001579576200157962004437565b9060005260206000209060030201600201548562001598919062004341565b94505b620015a860028462004373565b925060010162001510565b508660030154848860040154620015cb919062004373565b620015d791906200435c565b620015e3824762004395565b620015ef919062004395565b620015fb908662004341565b9450505050505b60008111620016485760405162461bcd60e51b815260206004820152601160248201527011549497d19553131657d4d31054d21151607a1b604482015260640162000be7565b6040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156200167f573d6000803e3d6000fd5b5060408051868152602081018390529081018590526001600160a01b038316907fd52551477a320999cde57bfa527233cd7a79f23cd5c9a1d73b20ca2dac999aa69060600160405180910390a25050505050565b600080620016e062001dfa565b9050600060c960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200173357600080fd5b505afa15801562001748573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200176e91906200404f565b90508315620017865762001783858362004395565b91505b81158062001792575080155b15620017a3578492505050620017c1565b81620017b0828762004373565b620017bc91906200435c565b925050505b92915050565b600080600080670de0b6b3a7640000620017e062002c2c565b620017ec908762004373565b620017f891906200435c565b9050600062001806620025bf565b905080821162001820575092506000915081905062001b70565b60cf546000908190815b8181101562001b3557600081815260da60205260409020546001600160a01b0316801562001b2b576000816001600160a01b031663fb7795936040518163ffffffff1660e01b815260040160206040518083038186803b1580156200188e57600080fd5b505afa158015620018a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c991906200404f565b60ca5460405163cfd4766360e01b81526001600160a01b0385811660048301526024820184905292935091169063cfd476639060440160206040518083038186803b1580156200191857600080fd5b505afa1580156200192d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200195391906200404f565b6200195f908762004341565b60ca5460405163cfdbb7cd60e01b81526001600160a01b0385811660048301526024820185905292985091169063cfdbb7cd9060440160206040518083038186803b158015620019ae57600080fd5b505afa158015620019c3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620019e991906200402f565b1562001b29576000826001600160a01b0316632b1931fe6040518163ffffffff1660e01b815260040160206040518083038186803b15801562001a2b57600080fd5b505afa15801562001a40573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001a6691906200404f565b60ca54604051635fb45b5360e01b81526001600160a01b039182166004820152908516602482015260448101849052606481018290526084810182905290915073__$5d081bb259322a68472281687e69aa3f61$__90635fb45b539060a40160206040518083038186803b15801562001ade57600080fd5b505af415801562001af3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b1991906200404f565b62001b25908762004341565b9550505b505b506001016200182a565b50600062001b44858762004395565b905060008462001b55858462004373565b62001b6191906200435c565b96995090975094955050505050505b9193909250565b62001b8162002ea6565b60d282905560d3819055604080518381526020810183905233917f6336de44e69f674663e4ef431d96ff47327224598c485ce7dd1c486ba216db1791015b60405180910390a25050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016141562001c175760405162461bcd60e51b815260040162000be7906200425e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031662001c6260008051602062005971833981519152546001600160a01b031690565b6001600160a01b03161462001c8b5760405162461bcd60e51b815260040162000be790620042aa565b62001c968262002f02565b62001ca48282600162002f0c565b5050565b60d45460ff161562001cfd5760405162461bcd60e51b815260206004820152601860248201527f4552525f554e44454c45474154455f49535f5041555345440000000000000000604482015260640162000be7565b62001d0b338484846200311a565b604080518481526020810184905233917f0eb3707116738c7f5ecbd2c2ee16e61ef2f6cf835efff5fb328938561486a2e4910162000f49565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161462001de65760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840162000be7565b506000805160206200597183398151915290565b60008062001e07620025bf565b60cf5490915060005b8181101562001ec657600081815260da60205260409020546001600160a01b0316801562001ebc57806001600160a01b031663646ce0106040518163ffffffff1660e01b815260040160206040518083038186803b15801562001e7257600080fd5b505afa15801562001e87573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001ead91906200404f565b62001eb9908562004341565b93505b5060010162001e10565b5060d95460005b8181101562001f8e57600060d9828154811062001eee5762001eee62004437565b6000918252602091829020015460408051630646ce0160e41b815290516001600160a01b039092169350839263646ce01092600480840193829003018186803b15801562001f3b57600080fd5b505afa15801562001f50573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001f7691906200404f565b62001f82908662004341565b94505060010162001ecd565b50919392505050565b600081815260db60209081526040808320805482518185028101850190935280835260609492939192909184015b828210156200201c576000848152602090819020604080516060810182526003860290920180546001600160a01b031683526001808201548486015260029091015491830191909152908352909201910162001fc5565b505050509050919050565b60d45462010000900460ff1615620020825760405162461bcd60e51b815260206004820152601b60248201527f4552525f544849535f46554e4354494f4e5f49535f5041555345440000000000604482015260640162000be7565b60ca5460408051630ecce30160e31b815290516000926001600160a01b0316916376671808916004808301926020929190829003018186803b158015620020c857600080fd5b505afa158015620020dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200210391906200404f565b905060ce548111620021125750565b60ce81905560cf54479060005b818110156200215e57600081815260da60205260409020546001600160a01b031680156200215457620021528162002e41565b505b506001016200211f565b5060cd5415620021d85760cd5447906000906127109062002180868562004395565b6200218c919062004373565b6200219891906200435c565b60cc546040519192506001600160a01b03169082156108fc029083906000818181858888f19350505050158015620021d4573d6000803e3d6000fd5b5050505b505050565b620021e762002ea6565b60405163880cdc3160e01b81526001600160a01b03828116600483015283169063880cdc3190602401600060405180830381600087803b1580156200222b57600080fd5b505af115801562002240573d6000803e3d6000fd5b5050604080516001600160a01b038681168252851660208201523393507f613a5b1d714fb5a78efb4fba0430702fa82a9e37b373f195d4d4b7dcb4b970c892500162001bbf565b6200229162002ea6565b6200229d600062003611565b565b60cf54606090600090818167ffffffffffffffff811115620022c557620022c56200444d565b6040519080825280602002602001820160405280156200232657816020015b62002312604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b815260200190600190039081620022e45790505b5060d5549091506000805b8715620024495762002344838662003663565b600081815260da60205260409020549093506001600160a01b0316806200236c575062002449565b60008060006200237d848d62003693565b9250925092508388878151811062002399576200239962004437565b6020026020010151600001906001600160a01b031690816001600160a01b03168152505082888781518110620023d357620023d362004437565b6020026020010151602001818152505081888781518110620023f957620023f962004437565b60209081029190910101516040015262002414828462004395565b62002420908662004341565b94506200242e818d62004395565b9b506200243d60018762004341565b95505050505062002331565b60008267ffffffffffffffff8111156200246757620024676200444d565b604051908082528060200260200182016040528015620024c857816020015b620024b4604051806060016040528060006001600160a01b0316815260200160008152602001600081525090565b815260200190600190039081620024865790505b50905060005b838110156200252757858181518110620024ec57620024ec62004437565b602002602001015182828151811062002509576200250962004437565b60200260200101819052506200251f8160010190565b9050620024ce565b509890975095505050505050565b6200253f62002ea6565b612710811115620025875760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f56414c554560781b604482015260640162000be7565b60cd55565b600060d98281548110620025a457620025a462004437565b6000918252602090912001546001600160a01b031692915050565b600060d85447620025d1919062004395565b905090565b620025e062002ea6565b60d45460ff1615158115151415620026375760405162461bcd60e51b81526020600482015260196024820152784552525f414c52454144595f444553495245445f56414c554560381b604482015260640162000be7565b60d4805460ff191682151590811790915560405190815233907fd009bec484226a9cd47773e930e5c5ba25d927bd3422e7fe83dbd8c3dfefa0f39060200162000f93565b60d2543490811080159062002692575060d3548111155b620026e05760405162461bcd60e51b815260206004820152601960248201527f4552525f414d4f554e545f4f5554534944455f4c494d49545300000000000000604482015260640162000be7565b6000620026ef826001620016d3565b60c9546040516340c10f1960e01b8152336004820152602481018390529192506001600160a01b0316906340c10f1990604401600060405180830381600087803b1580156200273d57600080fd5b505af115801562002752573d6000803e3d6000fd5b505060408051348152602081018590523393507f8de097f054bf5282188a61136aa10aff99a4a5ad0ca0985010a52dbc83f8bfd592500162001bbf565b6200279962002ea6565b60d45460ff620100009091041615158115151415620027f75760405162461bcd60e51b81526020600482015260196024820152784552525f414c52454144595f444553495245445f56414c554560381b604482015260640162000be7565b60d48054821515620100000262ff00001990911617905560405133907f1a480001006251004b925e05a0c5f3c8cbc7630eee9e6cdc45a865fa3fd9334f9062000f9390841515815260200190565b600054610100900460ff1615808015620028665750600054600160ff909116105b80620028825750303b15801562002882575060005460ff166001145b620028e75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840162000be7565b6000805460ff1916600117905580156200290b576000805461ff0019166101001790555b6200291562003957565b6200291f6200398b565b60c980546001600160a01b038089166001600160a01b03199283161790925560ca80549288169282169290921790915560cf85905560d084905560d183905560cc805490911633179055600060d25568056bc75e2d6310000060d3558015620021d4576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050505050565b620029d362002ea6565b60d181905560405181815233907f36ac5862acb8a66c4b3141acc98a2d72ffc2e0f05045a1bf1709a2acea66dbd79060200162000f93565b62002a1562002ea6565b60cb80546001600160a01b0319166001600160a01b03831690811790915560405190815233907f49f7c39d3a1550780f0253120b78fb960ba7c07494f86aa7cc30299b00a8374a9060200162000f93565b62002a7062002ea6565b60d75442101562002ac45760405162461bcd60e51b815260206004820152601760248201527f4552525f574149545f464f525f4e4558545f45504f4348000000000000000000604482015260640162000be7565b60008111801562002ade575062002ada620025bf565b8111155b62002b215760405162461bcd60e51b815260206004820152601260248201527111549497d253959053125117d05353d5539560721b604482015260640162000be7565b60d05460d7600082825462002b37919062004341565b909155505060cb54604051631bf02e6b60e11b81526004810183905260009182916001600160a01b03909116906337e05cd6906024016040805180830381600087803b15801562002b8757600080fd5b505af115801562002b9c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002bc2919062004124565b91509150600062002bd383620039b5565b905062002be281838662003aa4565b60408051838152602081018690526001600160a01b038316917f22af55bbeeb3fac1ac53cea63fa630fadfb2eb7a5815b44870d84d8ee437d5bd910160405180910390a250505050565b60008062002c3962001dfa565b9050600060c960009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801562002c8c57600080fd5b505afa15801562002ca1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002cc791906200404f565b905081158062002cd5575080155b1562002cf75762002cf0670de0b6b3a7640000600162004373565b9250505090565b8062002d0c670de0b6b3a76400008462004373565b62002cf091906200435c565b62002d2262002ea6565b6001600160a01b03811662002d6e5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f56414c554560781b604482015260640162000be7565b60cc80546001600160a01b0319166001600160a01b0392909216919091179055565b62002d9a62002ea6565b6001600160a01b03811662002e015760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000be7565b620010878162003611565b606462002e23670de0b6b3a7640000601e62004373565b62002e2f91906200435c565b81565b6001600160a01b03163b151590565b6000816001600160a01b031663372500ab6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562002e7f57600080fd5b505af192505050801562002e91575060015b62002e9e57506000919050565b506001919050565b6033546001600160a01b031633146200229d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000be7565b6200108762002ea6565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161562002f4257620021d88362003b30565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b815260040160206040518083038186803b15801562002f7c57600080fd5b505afa92505050801562002faf575060408051601f3d908101601f1916820190925262002fac918101906200404f565b60015b620030145760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b606482015260840162000be7565b600080516020620059718339815191528114620030865760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b606482015260840162000be7565b50620021d883838362003bcf565b604051631c683a1b60e11b81526004810183905281151560248201526001600160a01b038416906338d07436906044015b600060405180830381600087803b158015620030e057600080fd5b505af1158015620030f5573d6000803e3d6000fd5b50505050505050565b8060d8600082825462003112919062004395565b909155505050565b600082116200315e5760405162461bcd60e51b815260206004820152600f60248201526e11549497d6915493d7d05353d55395608a1b604482015260640162000be7565b60008311620031b05760405162461bcd60e51b815260206004820152601960248201527f4552525f777249445f4d5553545f42455f4e4f4e5f5a45524f00000000000000604482015260640162000be7565b600083815260db60205260409020600181015415620032125760405162461bcd60e51b815260206004820152601560248201527f4552525f575249445f414c52454144595f555345440000000000000000000000604482015260640162000be7565b4260018201556005810180546001600160a01b0319166001600160a01b038716179055600080806200324486620017c7565b919450925090508462003258828562004395565b1015620032a85760405162461bcd60e51b815260206004820152601b60248201527f4552525f494e53554646494349454e545f414d4f554e545f4f55540000000000604482015260640162000be7565b60c95460405163079cc67960e41b81526001600160a01b038a8116600483015260248201899052909116906379cc679090604401600060405180830381600087803b158015620032f757600080fd5b505af11580156200330c573d6000803e3d6000fd5b5050505081600014156200333257620033258362003c00565b6002840183905562003607565b6200334862003342838562004395565b62003c00565b60008062003356846200229f565b815160cf5460d5549395509193509160005b83811015620035ca57620033df8682815181106200338a576200338a62004437565b6020026020010151600001518e888481518110620033ac57620033ac62004437565b602002602001015160200151898581518110620033cd57620033cd62004437565b60200260200101516040015162003c14565b620033ec60018562004395565b811080620034a357506200340260018562004395565b81148015620034a3575085818151811062003421576200342162004437565b6020026020010151600001516001600160a01b0316632b1931fe6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200346657600080fd5b505afa1580156200347b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620034a191906200404f565b155b15620034ed57620034b5828462003663565b600081815260da6020526040902080546001600160a01b03191690559150620034dd62003ccf565b620034ed60d68054600019019055565b89600001604051806060016040528088848151811062003511576200351162004437565b6020026020010151600001516001600160a01b0316815260200188848151811062003540576200354062004437565b602002602001015160200151815260200188848151811062003566576200356662004437565b602090810291909101810151604090810151909252835460018082018655600095865294829020845160039092020180546001600160a01b0319166001600160a01b0390921691909117815590830151818501559101516002909101550162003368565b50620035d7878962004395565b60028a01556003890187905585841115620035f0578593505b620035fc848762004395565b60048a015550505050505b5050505050505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600081600162003674828662004341565b62003680919062004395565b6200368c9190620043de565b9392505050565b600080600080856001600160a01b031663fb7795936040518163ffffffff1660e01b815260040160206040518083038186803b158015620036d357600080fd5b505afa158015620036e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200370e91906200404f565b90506000866001600160a01b0316632b1931fe6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200374c57600080fd5b505afa15801562003761573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200378791906200404f565b60ca54604051635fb45b5360e01b81526001600160a01b039182166004820152908916602482015260448101849052606481018290526084810182905290915060009073__$5d081bb259322a68472281687e69aa3f61$__90635fb45b539060a40160206040518083038186803b1580156200380257600080fd5b505af415801562003817573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200383d91906200404f565b62003849908362004395565b905086811115620039465760008162003863848a62004373565b6200386f91906200435c565b60ca54604051635fb45b5360e01b81526001600160a01b039182166004820152908b16602482015260448101869052606481018290526084810185905290915060009073__$5d081bb259322a68472281687e69aa3f61$__90635fb45b539060a40160206040518083038186803b158015620038ea57600080fd5b505af4158015620038ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200392591906200404f565b90508162003934828262004395565b8a975097509750505050505062003950565b9094509250829150505b9250925092565b600054610100900460ff16620039815760405162461bcd60e51b815260040162000be790620042f6565b6200229d62003ce4565b600054610100900460ff166200229d5760405162461bcd60e51b815260040162000be790620042f6565b600060cf5460d6541062003a0c5760405162461bcd60e51b815260206004820152601760248201527f4552525f4d41585f5641554c54535f4f43435550494544000000000000000000604482015260640162000be7565b60ca546040516000916001600160a01b031690849062003a2c9062003ed3565b6001600160a01b0390921682526020820152604001604051809103906000f08015801562003a5e573d6000803e3d6000fd5b5060d554600090815260da6020526040902080546001600160a01b0319166001600160a01b038316179055905062003a9562003d19565b620017c160d680546001019055565b826001600160a01b031663c89e4361826040518263ffffffff1660e01b81526004016000604051808303818588803b15801562003ae057600080fd5b505af115801562003af5573d6000803e3d6000fd5b505060405163a97aeed560e01b815260048101869052602481018590526001600160a01b038716935063a97aeed592506044019050620030c5565b6001600160a01b0381163b62003b9f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000be7565b6000805160206200597183398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b62003bda8362003d29565b60008251118062003be85750805b15620021d85762003bfa838362003d6b565b50505050565b8060d8600082825462003112919062004341565b604051636198e33960e01b8152600481018390526001600160a01b03851690636198e33990602401600060405180830381600087803b15801562003c5757600080fd5b505af115801562003c6c573d6000803e3d6000fd5b505060405163634b91e360e01b815260048101869052602481018490526001600160a01b038716925063634b91e39150604401600060405180830381600087803b15801562003cba57600080fd5b505af115801562003607573d6000803e3d6000fd5b62003cdf60d55460cf5462003663565b60d555565b600054610100900460ff1662003d0e5760405162461bcd60e51b815260040162000be790620042f6565b6200229d3362003611565b62003cdf60d55460cf5462003d93565b62003d348162003b30565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200368c8383604051806060016040528060278152602001620059916027913962003da3565b6000816200368084600162004341565b6060600080856001600160a01b03168560405162003dc29190620041d2565b600060405180830381855af49150503d806000811462003dff576040519150601f19603f3d011682016040523d82523d6000602084013e62003e04565b606091505b509150915062003e178683838762003e21565b9695505050505050565b6060831562003e9257825162003e8a576001600160a01b0385163b62003e8a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000be7565b508162003e9e565b62003e9e838362003ea6565b949350505050565b81511562003eb75781518083602001fd5b8060405162461bcd60e51b815260040162000be7919062004229565b6114e8806200448983390190565b60006020828403121562003ef457600080fd5b81356200368c8162004463565b6000806040838503121562003f1557600080fd5b823562003f228162004463565b9150602083013562003f348162004463565b809150509250929050565b6000806040838503121562003f5357600080fd5b823562003f608162004463565b9150602083013567ffffffffffffffff8082111562003f7e57600080fd5b818501915085601f83011262003f9357600080fd5b81358181111562003fa85762003fa86200444d565b604051601f8201601f19908116603f0116810190838211818310171562003fd35762003fd36200444d565b8160405282815288602084870101111562003fed57600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000602082840312156200402257600080fd5b81356200368c8162004479565b6000602082840312156200404257600080fd5b81516200368c8162004479565b6000602082840312156200406257600080fd5b5051919050565b600080600080600060a086880312156200408257600080fd5b85356200408f8162004463565b94506020860135620040a18162004463565b94979496505050506040830135926060810135926080909101359150565b600060208284031215620040d257600080fd5b5035919050565b60008060408385031215620040ed57600080fd5b82359150602083013562003f348162004479565b600080604083850312156200411557600080fd5b50508035926020909101359150565b600080604083850312156200413857600080fd5b505080516020909101519092909150565b6000806000606084860312156200415f57600080fd5b505081359360208301359350604090920135919050565b600081518084526020808501945080840160005b83811015620041c757815180516001600160a01b03168852838101518489015260409081015190880152606090960195908201906001016200418a565b509495945050505050565b60008251620041e6818460208701620043af565b9190910192915050565b6020815260006200368c602083018462004176565b6040815260006200421a604083018562004176565b90508260208301529392505050565b60208152600082518060208401526200424a816040850160208701620043af565b601f01601f19169190910160400192915050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60008219821115620043575762004357620043f5565b500190565b6000826200436e576200436e6200440b565b500490565b6000816000190483118215151615620043905762004390620043f5565b500290565b600082821015620043aa57620043aa620043f5565b500390565b60005b83811015620043cc578181015183820152602001620043b2565b8381111562003bfa5750506000910152565b600082620043f057620043f06200440b565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146200108757600080fd5b80151581146200108757600080fdfe60e06040523480156200001157600080fd5b50604051620014e8380380620014e88339810160408190526200003491620000f9565b600080546001600160a01b031916331781556001600160601b0319606084901b1660805260c082905260405163b5d8962760e01b8152600481018390526001600160a01b0384169063b5d896279060240160e06040518083038186803b1580156200009e57600080fd5b505afa158015620000b3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d991906200012a565b60601b6001600160601b03191660a05250620001a6975050505050505050565b600080604083850312156200010d57600080fd5b82516200011a816200018d565b6020939093015192949293505050565b600080600080600080600060e0888a0312156200014657600080fd5b875196506020880151955060408801519450606088015193506080880151925060a0880151915060c08801516200017d816200018d565b8091505092959891949750929550565b6001600160a01b0381168114620001a357600080fd5b50565b60805160601c60a05160601c60c051611248620002a06000396000818161030d0152818161037f0152818161047101528181610570015281816106930152818161075801528181610846015281816108f8015281816109ba01528181610a7d01528181610b4001528181610d1501528181610db901528181610e790152610ef301526000610205015260008181610291015281816103a8015281816104970152818161059f015281816106b9015281816107850152818161087a0152818161092b015281816109ee01528181610ab701528181610b7801528181610d4901528181610ddf01528181610ead0152610f2601526112486000f3fe6080604052600436106101025760003560e01c806368d57d3f11610095578063a97aeed511610064578063a97aeed5146102b3578063c89e4361146102d3578063e0819cd4146102db578063fb779593146102fb578063ffa1ad741461032f57600080fd5b806368d57d3f146101f3578063880cdc311461023f5780638da5cb5b1461025f5780639094631e1461027f57600080fd5b80633d8527ba116100d15780633d8527ba146101895780636198e3391461019e578063634b91e3146101be578063646ce010146101de57600080fd5b80630fa67db21461010e5780632b1931fe1461013d578063372500ab1461015257806338d074361461016957600080fd5b3661010957005b600080fd5b34801561011a57600080fd5b5061012a670de0b6b3a764000081565b6040519081526020015b60405180910390f35b34801561014957600080fd5b5061012a61036a565b34801561015e57600080fd5b5061016761042f565b005b34801561017557600080fd5b5061016761018436600461107f565b610537565b34801561019557600080fd5b5061016761065a565b3480156101aa57600080fd5b506101676101b936600461104d565b61071f565b3480156101ca57600080fd5b506101676101d93660046110af565b61080d565b3480156101ea57600080fd5b5061012a6108e3565b3480156101ff57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610134565b34801561024b57600080fd5b5061016761025a366004611007565b610c39565b34801561026b57600080fd5b50600054610227906001600160a01b031681565b34801561028b57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b3480156102bf57600080fd5b506101676102ce3660046110af565b610cdc565b610167610d80565b3480156102e757600080fd5b506101676102f63660046110af565b610e40565b34801561030757600080fd5b5061012a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561033b57600080fd5b5061035d60405180604001604052806002815260200161763160f01b81525081565b60405161013491906110ff565b604051630ce0645f60e31b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063670322f89060440160206040518083038186803b1580156103f257600080fd5b505afa158015610406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042a9190611066565b905090565b6000546001600160a01b031633146104625760405162461bcd60e51b815260040161045990611154565b60405180910390fd5b604051630962ef7960e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630962ef7990602401600060405180830381600087803b1580156104e357600080fd5b505af11580156104f7573d6000803e3d6000fd5b5050600080546040516001600160a01b0390911693504780156108fc02935091818181858888f19350505050158015610534573d6000803e3d6000fd5b50565b6000546001600160a01b031633146105615760405162461bcd60e51b815260040161045990611154565b604051630441a3e760e41b81527f000000000000000000000000000000000000000000000000000000000000000060048201526024810183905247907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063441a3e7090604401600060405180830381600087803b1580156105eb57600080fd5b505af11580156105ff573d6000803e3d6000fd5b5050505060004790508261061a5761061782826111d7565b90505b600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610653573d6000803e3d6000fd5b5050505050565b6000546001600160a01b031633146106845760405162461bcd60e51b815260040161045990611154565b604051630230da1d60e21b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906308c3687490602401600060405180830381600087803b15801561070557600080fd5b505af1158015610719573d6000803e3d6000fd5b50505050565b6000546001600160a01b031633146107495760405162461bcd60e51b815260040161045990611154565b60405163074eb10b60e21b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631d3ac42c90604401602060405180830381600087803b1580156107d157600080fd5b505af11580156107e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108099190611066565b5050565b6000546001600160a01b031633146108375760405162461bcd60e51b815260040161045990611154565b6040516313e1937d60e21b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634f864df4906064015b600060405180830381600087803b1580156108c757600080fd5b505af11580156108db573d6000803e3d6000fd5b505050505050565b60405163cfd4766360e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000602482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cfd476639060440160206040518083038186803b15801561096d57600080fd5b505afa158015610981573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a59190611066565b60405163304cf65960e11b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201529091506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636099ecb29060440160206040518083038186803b158015610a3057600080fd5b505afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a689190611066565b604051630f9380a960e11b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201526000604482018190529192506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631f2701529060640160606040518083038186803b158015610af957600080fd5b505afa158015610b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3191906110d1565b6040516361ef2c0760e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152909350600092508291506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c3de580e9060240160206040518083038186803b158015610bba57600080fd5b505afa158015610bce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf29190611030565b90508015610c0f57610c0c610c07848761117e565b610ee4565b91505b8183610c1b868861117e565b610c25919061117e565b610c2f91906111d7565b9550505050505090565b6000546001600160a01b03163314610c635760405162461bcd60e51b815260040161045990611154565b6001600160a01b038116610cad5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f56414c554560781b6044820152606401610459565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610d065760405162461bcd60e51b815260040161045990611154565b60405163de67f21560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063de67f215906064016108ad565b6000546001600160a01b03163314610daa5760405162461bcd60e51b815260040161045990611154565b604051639fa6dd3560e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639fa6dd359034906024016000604051808303818588803b158015610e2c57600080fd5b505af1158015610653573d6000803e3d6000fd5b6000546001600160a01b03163314610e6a5760405162461bcd60e51b815260040161045990611154565b60405163bd14d90760e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bd14d907906064016108ad565b60405163c65ee0e160e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c65ee0e19060240160206040518083038186803b158015610f6857600080fd5b505afa158015610f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa09190611066565b9050670de0b6b3a76400008110610fba5750600092915050565b6000670de0b6b3a7640000610fcf83826111d7565b610fd990866111b8565b610fe39190611196565b610fee90600161117e565b90508381111561100057509192915050565b9392505050565b60006020828403121561101957600080fd5b81356001600160a01b038116811461100057600080fd5b60006020828403121561104257600080fd5b815161100081611204565b60006020828403121561105f57600080fd5b5035919050565b60006020828403121561107857600080fd5b5051919050565b6000806040838503121561109257600080fd5b8235915060208301356110a481611204565b809150509250929050565b600080604083850312156110c257600080fd5b50508035926020909101359150565b6000806000606084860312156110e657600080fd5b8351925060208401519150604084015190509250925092565b600060208083528351808285015260005b8181101561112c57858101830151858201604001528201611110565b8181111561113e576000604083870101525b50601f01601f1916929092016040019392505050565b60208082526010908201526f11549497d5539055551213d49256915160821b604082015260600190565b60008219821115611191576111916111ee565b500190565b6000826111b357634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156111d2576111d26111ee565b500290565b6000828210156111e9576111e96111ee565b500390565b634e487b7160e01b600052601160045260246000fd5b801515811461053457600080fdfea2646970667358221220b4bd5ef8f0e940a42d9dac8a22de871688b9cc3cc9a6aa731612b041280bdeb864736f6c63430008070033360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220377fdff03fc22d21ced4fc4368b0119db847edd7e3624e817e3409329ddca84764736f6c63430008070033", + "linkReferences": { + "contracts/libraries/SFCPenalty.sol": { + "SFCPenalty": [ + { + "length": 20, + "start": 7222 + }, + { + "length": 20, + "start": 14682 + }, + { + "length": 20, + "start": 14914 + } + ] + } + }, + "deployedLinkReferences": { + "contracts/libraries/SFCPenalty.sol": { + "SFCPenalty": [ + { + "length": 20, + "start": 6824 + }, + { + "length": 20, + "start": 14284 + }, + { + "length": 20, + "start": 14516 + } + ] + } + } +} diff --git a/modules/sftmx/abi/Vault.json b/modules/sftmx/abi/Vault.json new file mode 100644 index 000000000..ec84df00d --- /dev/null +++ b/modules/sftmx/abi/Vault.json @@ -0,0 +1,254 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "Vault", + "sourceName": "contracts/Vault.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ISFC", + "name": "_sfc", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_toValidatorID", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "DECIMAL_UNIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SFC", + "outputs": [ + { + "internalType": "contract ISFC", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "currentStakeValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "delegate", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getLockedStake", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lockupDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "lockStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "lockupDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "relockStake", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "restakeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "toValidator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "toValidatorID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wrID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "undelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "unlock", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "updateOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "wrID", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "sendAll", + "type": "bool" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x60e06040523480156200001157600080fd5b50604051620014e8380380620014e88339810160408190526200003491620000f9565b600080546001600160a01b031916331781556001600160601b0319606084901b1660805260c082905260405163b5d8962760e01b8152600481018390526001600160a01b0384169063b5d896279060240160e06040518083038186803b1580156200009e57600080fd5b505afa158015620000b3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d991906200012a565b60601b6001600160601b03191660a05250620001a6975050505050505050565b600080604083850312156200010d57600080fd5b82516200011a816200018d565b6020939093015192949293505050565b600080600080600080600060e0888a0312156200014657600080fd5b875196506020880151955060408801519450606088015193506080880151925060a0880151915060c08801516200017d816200018d565b8091505092959891949750929550565b6001600160a01b0381168114620001a357600080fd5b50565b60805160601c60a05160601c60c051611248620002a06000396000818161030d0152818161037f0152818161047101528181610570015281816106930152818161075801528181610846015281816108f8015281816109ba01528181610a7d01528181610b4001528181610d1501528181610db901528181610e790152610ef301526000610205015260008181610291015281816103a8015281816104970152818161059f015281816106b9015281816107850152818161087a0152818161092b015281816109ee01528181610ab701528181610b7801528181610d4901528181610ddf01528181610ead0152610f2601526112486000f3fe6080604052600436106101025760003560e01c806368d57d3f11610095578063a97aeed511610064578063a97aeed5146102b3578063c89e4361146102d3578063e0819cd4146102db578063fb779593146102fb578063ffa1ad741461032f57600080fd5b806368d57d3f146101f3578063880cdc311461023f5780638da5cb5b1461025f5780639094631e1461027f57600080fd5b80633d8527ba116100d15780633d8527ba146101895780636198e3391461019e578063634b91e3146101be578063646ce010146101de57600080fd5b80630fa67db21461010e5780632b1931fe1461013d578063372500ab1461015257806338d074361461016957600080fd5b3661010957005b600080fd5b34801561011a57600080fd5b5061012a670de0b6b3a764000081565b6040519081526020015b60405180910390f35b34801561014957600080fd5b5061012a61036a565b34801561015e57600080fd5b5061016761042f565b005b34801561017557600080fd5b5061016761018436600461107f565b610537565b34801561019557600080fd5b5061016761065a565b3480156101aa57600080fd5b506101676101b936600461104d565b61071f565b3480156101ca57600080fd5b506101676101d93660046110af565b61080d565b3480156101ea57600080fd5b5061012a6108e3565b3480156101ff57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610134565b34801561024b57600080fd5b5061016761025a366004611007565b610c39565b34801561026b57600080fd5b50600054610227906001600160a01b031681565b34801561028b57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b3480156102bf57600080fd5b506101676102ce3660046110af565b610cdc565b610167610d80565b3480156102e757600080fd5b506101676102f63660046110af565b610e40565b34801561030757600080fd5b5061012a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561033b57600080fd5b5061035d60405180604001604052806002815260200161763160f01b81525081565b60405161013491906110ff565b604051630ce0645f60e31b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063670322f89060440160206040518083038186803b1580156103f257600080fd5b505afa158015610406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042a9190611066565b905090565b6000546001600160a01b031633146104625760405162461bcd60e51b815260040161045990611154565b60405180910390fd5b604051630962ef7960e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630962ef7990602401600060405180830381600087803b1580156104e357600080fd5b505af11580156104f7573d6000803e3d6000fd5b5050600080546040516001600160a01b0390911693504780156108fc02935091818181858888f19350505050158015610534573d6000803e3d6000fd5b50565b6000546001600160a01b031633146105615760405162461bcd60e51b815260040161045990611154565b604051630441a3e760e41b81527f000000000000000000000000000000000000000000000000000000000000000060048201526024810183905247907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063441a3e7090604401600060405180830381600087803b1580156105eb57600080fd5b505af11580156105ff573d6000803e3d6000fd5b5050505060004790508261061a5761061782826111d7565b90505b600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610653573d6000803e3d6000fd5b5050505050565b6000546001600160a01b031633146106845760405162461bcd60e51b815260040161045990611154565b604051630230da1d60e21b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906308c3687490602401600060405180830381600087803b15801561070557600080fd5b505af1158015610719573d6000803e3d6000fd5b50505050565b6000546001600160a01b031633146107495760405162461bcd60e51b815260040161045990611154565b60405163074eb10b60e21b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631d3ac42c90604401602060405180830381600087803b1580156107d157600080fd5b505af11580156107e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108099190611066565b5050565b6000546001600160a01b031633146108375760405162461bcd60e51b815260040161045990611154565b6040516313e1937d60e21b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634f864df4906064015b600060405180830381600087803b1580156108c757600080fd5b505af11580156108db573d6000803e3d6000fd5b505050505050565b60405163cfd4766360e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000602482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cfd476639060440160206040518083038186803b15801561096d57600080fd5b505afa158015610981573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a59190611066565b60405163304cf65960e11b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201529091506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636099ecb29060440160206040518083038186803b158015610a3057600080fd5b505afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a689190611066565b604051630f9380a960e11b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201526000604482018190529192506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631f2701529060640160606040518083038186803b158015610af957600080fd5b505afa158015610b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3191906110d1565b6040516361ef2c0760e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152909350600092508291506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c3de580e9060240160206040518083038186803b158015610bba57600080fd5b505afa158015610bce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf29190611030565b90508015610c0f57610c0c610c07848761117e565b610ee4565b91505b8183610c1b868861117e565b610c25919061117e565b610c2f91906111d7565b9550505050505090565b6000546001600160a01b03163314610c635760405162461bcd60e51b815260040161045990611154565b6001600160a01b038116610cad5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f56414c554560781b6044820152606401610459565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610d065760405162461bcd60e51b815260040161045990611154565b60405163de67f21560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063de67f215906064016108ad565b6000546001600160a01b03163314610daa5760405162461bcd60e51b815260040161045990611154565b604051639fa6dd3560e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639fa6dd359034906024016000604051808303818588803b158015610e2c57600080fd5b505af1158015610653573d6000803e3d6000fd5b6000546001600160a01b03163314610e6a5760405162461bcd60e51b815260040161045990611154565b60405163bd14d90760e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bd14d907906064016108ad565b60405163c65ee0e160e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c65ee0e19060240160206040518083038186803b158015610f6857600080fd5b505afa158015610f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa09190611066565b9050670de0b6b3a76400008110610fba5750600092915050565b6000670de0b6b3a7640000610fcf83826111d7565b610fd990866111b8565b610fe39190611196565b610fee90600161117e565b90508381111561100057509192915050565b9392505050565b60006020828403121561101957600080fd5b81356001600160a01b038116811461100057600080fd5b60006020828403121561104257600080fd5b815161100081611204565b60006020828403121561105f57600080fd5b5035919050565b60006020828403121561107857600080fd5b5051919050565b6000806040838503121561109257600080fd5b8235915060208301356110a481611204565b809150509250929050565b600080604083850312156110c257600080fd5b50508035926020909101359150565b6000806000606084860312156110e657600080fd5b8351925060208401519150604084015190509250925092565b600060208083528351808285015260005b8181101561112c57858101830151858201604001528201611110565b8181111561113e576000604083870101525b50601f01601f1916929092016040019392505050565b60208082526010908201526f11549497d5539055551213d49256915160821b604082015260600190565b60008219821115611191576111916111ee565b500190565b6000826111b357634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156111d2576111d26111ee565b500290565b6000828210156111e9576111e96111ee565b500390565b634e487b7160e01b600052601160045260246000fd5b801515811461053457600080fdfea2646970667358221220b4bd5ef8f0e940a42d9dac8a22de871688b9cc3cc9a6aa731612b041280bdeb864736f6c63430008070033", + "deployedBytecode": "0x6080604052600436106101025760003560e01c806368d57d3f11610095578063a97aeed511610064578063a97aeed5146102b3578063c89e4361146102d3578063e0819cd4146102db578063fb779593146102fb578063ffa1ad741461032f57600080fd5b806368d57d3f146101f3578063880cdc311461023f5780638da5cb5b1461025f5780639094631e1461027f57600080fd5b80633d8527ba116100d15780633d8527ba146101895780636198e3391461019e578063634b91e3146101be578063646ce010146101de57600080fd5b80630fa67db21461010e5780632b1931fe1461013d578063372500ab1461015257806338d074361461016957600080fd5b3661010957005b600080fd5b34801561011a57600080fd5b5061012a670de0b6b3a764000081565b6040519081526020015b60405180910390f35b34801561014957600080fd5b5061012a61036a565b34801561015e57600080fd5b5061016761042f565b005b34801561017557600080fd5b5061016761018436600461107f565b610537565b34801561019557600080fd5b5061016761065a565b3480156101aa57600080fd5b506101676101b936600461104d565b61071f565b3480156101ca57600080fd5b506101676101d93660046110af565b61080d565b3480156101ea57600080fd5b5061012a6108e3565b3480156101ff57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610134565b34801561024b57600080fd5b5061016761025a366004611007565b610c39565b34801561026b57600080fd5b50600054610227906001600160a01b031681565b34801561028b57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b3480156102bf57600080fd5b506101676102ce3660046110af565b610cdc565b610167610d80565b3480156102e757600080fd5b506101676102f63660046110af565b610e40565b34801561030757600080fd5b5061012a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561033b57600080fd5b5061035d60405180604001604052806002815260200161763160f01b81525081565b60405161013491906110ff565b604051630ce0645f60e31b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063670322f89060440160206040518083038186803b1580156103f257600080fd5b505afa158015610406573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042a9190611066565b905090565b6000546001600160a01b031633146104625760405162461bcd60e51b815260040161045990611154565b60405180910390fd5b604051630962ef7960e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630962ef7990602401600060405180830381600087803b1580156104e357600080fd5b505af11580156104f7573d6000803e3d6000fd5b5050600080546040516001600160a01b0390911693504780156108fc02935091818181858888f19350505050158015610534573d6000803e3d6000fd5b50565b6000546001600160a01b031633146105615760405162461bcd60e51b815260040161045990611154565b604051630441a3e760e41b81527f000000000000000000000000000000000000000000000000000000000000000060048201526024810183905247907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063441a3e7090604401600060405180830381600087803b1580156105eb57600080fd5b505af11580156105ff573d6000803e3d6000fd5b5050505060004790508261061a5761061782826111d7565b90505b600080546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015610653573d6000803e3d6000fd5b5050505050565b6000546001600160a01b031633146106845760405162461bcd60e51b815260040161045990611154565b604051630230da1d60e21b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906308c3687490602401600060405180830381600087803b15801561070557600080fd5b505af1158015610719573d6000803e3d6000fd5b50505050565b6000546001600160a01b031633146107495760405162461bcd60e51b815260040161045990611154565b60405163074eb10b60e21b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631d3ac42c90604401602060405180830381600087803b1580156107d157600080fd5b505af11580156107e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108099190611066565b5050565b6000546001600160a01b031633146108375760405162461bcd60e51b815260040161045990611154565b6040516313e1937d60e21b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634f864df4906064015b600060405180830381600087803b1580156108c757600080fd5b505af11580156108db573d6000803e3d6000fd5b505050505050565b60405163cfd4766360e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000602482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cfd476639060440160206040518083038186803b15801561096d57600080fd5b505afa158015610981573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a59190611066565b60405163304cf65960e11b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201529091506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636099ecb29060440160206040518083038186803b158015610a3057600080fd5b505afa158015610a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a689190611066565b604051630f9380a960e11b81523060048201527f000000000000000000000000000000000000000000000000000000000000000060248201526000604482018190529192506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631f2701529060640160606040518083038186803b158015610af957600080fd5b505afa158015610b0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3191906110d1565b6040516361ef2c0760e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152909350600092508291506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c3de580e9060240160206040518083038186803b158015610bba57600080fd5b505afa158015610bce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf29190611030565b90508015610c0f57610c0c610c07848761117e565b610ee4565b91505b8183610c1b868861117e565b610c25919061117e565b610c2f91906111d7565b9550505050505090565b6000546001600160a01b03163314610c635760405162461bcd60e51b815260040161045990611154565b6001600160a01b038116610cad5760405162461bcd60e51b81526020600482015260116024820152704552525f494e56414c49445f56414c554560781b6044820152606401610459565b6000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610d065760405162461bcd60e51b815260040161045990611154565b60405163de67f21560e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063de67f215906064016108ad565b6000546001600160a01b03163314610daa5760405162461bcd60e51b815260040161045990611154565b604051639fa6dd3560e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639fa6dd359034906024016000604051808303818588803b158015610e2c57600080fd5b505af1158015610653573d6000803e3d6000fd5b6000546001600160a01b03163314610e6a5760405162461bcd60e51b815260040161045990611154565b60405163bd14d90760e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bd14d907906064016108ad565b60405163c65ee0e160e01b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c65ee0e19060240160206040518083038186803b158015610f6857600080fd5b505afa158015610f7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa09190611066565b9050670de0b6b3a76400008110610fba5750600092915050565b6000670de0b6b3a7640000610fcf83826111d7565b610fd990866111b8565b610fe39190611196565b610fee90600161117e565b90508381111561100057509192915050565b9392505050565b60006020828403121561101957600080fd5b81356001600160a01b038116811461100057600080fd5b60006020828403121561104257600080fd5b815161100081611204565b60006020828403121561105f57600080fd5b5035919050565b60006020828403121561107857600080fd5b5051919050565b6000806040838503121561109257600080fd5b8235915060208301356110a481611204565b809150509250929050565b600080604083850312156110c257600080fd5b50508035926020909101359150565b6000806000606084860312156110e657600080fd5b8351925060208401519150604084015190509250925092565b600060208083528351808285015260005b8181101561112c57858101830151858201604001528201611110565b8181111561113e576000604083870101525b50601f01601f1916929092016040019392505050565b60208082526010908201526f11549497d5539055551213d49256915160821b604082015260600190565b60008219821115611191576111916111ee565b500190565b6000826111b357634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156111d2576111d26111ee565b500290565b6000828210156111e9576111e96111ee565b500390565b634e487b7160e01b600052601160045260246000fd5b801515811461053457600080fdfea2646970667358221220b4bd5ef8f0e940a42d9dac8a22de871688b9cc3cc9a6aa731612b041280bdeb864736f6c63430008070033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/modules/sftmx/sftmx.gql b/modules/sftmx/sftmx.gql new file mode 100644 index 000000000..4c46454ed --- /dev/null +++ b/modules/sftmx/sftmx.gql @@ -0,0 +1,33 @@ +extend type Query { + sftmxGetWithdrawalRequests(user: String!): [GqlSftmxWithdrawalRequests!]! + sftmxGetStakingData: GqlSftmxStakingData! +} + +extend type Mutation { + sftmxSyncWithdrawalRequests: String! + sftmxSyncStakingData: String! +} + +# TODO provide more info such as how much is staked on which validator +type GqlSftmxStakingData { + totalFtmAmount: AmountHumanReadable! + totalFtmAmountStaked: AmountHumanReadable! + totalFtmAmountInPool: AmountHumanReadable! + numberOfVaults: Int! + undelegatePaused: Boolean! + withdrawPaused: Boolean! + maintenancePaused: Boolean! + minDepositLimit: AmountHumanReadable! + maxDepositLimit: AmountHumanReadable! + exchangeRate: String! + stakingApr: String! + withdrawalDelay: Int! +} + +type GqlSftmxWithdrawalRequests { + id: String! + user: String! + amountSftmx: AmountHumanReadable! + requestTimestamp: Int! + isWithdrawn: Boolean! +} diff --git a/modules/sftmx/sftmx.prisma b/modules/sftmx/sftmx.prisma new file mode 100644 index 000000000..c9c381e8c --- /dev/null +++ b/modules/sftmx/sftmx.prisma @@ -0,0 +1,30 @@ + +model PrismaSftmxStakingData { + id String @id + totalFtm String + totalFtmStaked String + totalFtmInPool String + numberOfVaults Int + stakingApr String + exchangeRate String + + maxDepositLimit String + minDepositLimit String + withdrawalDelay Int + + undelegatePaused Boolean + withdrawPaused Boolean + maintenancePaused Boolean + + withdrawalRequests PrismaSftmxWithdrawalRequest[] +} + +model PrismaSftmxWithdrawalRequest { + id String @id + ftmStakingId PrismaSftmxStakingData @relation(fields:[id], references: [id]) + + user String + amountSftmx String + requestTimestamp Int + isWithdrawn Boolean +} diff --git a/modules/sftmx/sftmx.resolvers.ts b/modules/sftmx/sftmx.resolvers.ts new file mode 100644 index 000000000..8aea90dc4 --- /dev/null +++ b/modules/sftmx/sftmx.resolvers.ts @@ -0,0 +1,32 @@ +import { Resolvers } from '../../schema'; +import { isAdminRoute } from '../auth/auth-context'; +import { sftmxService } from './sftmx.service'; + +const resolvers: Resolvers = { + Query: { + sftmxGetWithdrawalRequests: async (parent, { user }, context) => { + return sftmxService.getWithdrawalRequests(user); + }, + sftmxGetStakingData: async (parent, {}, context) => { + return sftmxService.getStakingData(); + }, + }, + Mutation: { + sftmxSyncWithdrawalRequests: async (parent, {}, context) => { + isAdminRoute(context); + + await sftmxService.syncWithdrawalRequests(); + + return 'success'; + }, + sftmxSyncStakingData: async (parent, {}, context) => { + isAdminRoute(context); + + await sftmxService.syncStakingData(); + + return 'success'; + }, + }, +}; + +export default resolvers; diff --git a/modules/sftmx/sftmx.service.ts b/modules/sftmx/sftmx.service.ts new file mode 100644 index 000000000..894f863d8 --- /dev/null +++ b/modules/sftmx/sftmx.service.ts @@ -0,0 +1,158 @@ +import { prisma } from '../../prisma/prisma-client'; +import { GqlSftmxStakingData, GqlSftmxWithdrawalRequests } from '../../schema'; +import { SftmxSubgraphService } from '../subgraphs/sftmx-subgraph/sftmx.service'; +import { prismaBulkExecuteOperations } from '../../prisma/prisma-util'; +import { AllNetworkConfigsKeyedOnChain } from '../network/network-config'; +import { Multicaller3 } from '../web3/multicaller3'; +import FTMStaking from './abi/FTMStaking.json'; +import Vault from './abi/Vault.json'; +import { BigNumber } from 'ethers'; +import { formatFixed } from '@ethersproject/bignumber'; +import { getContractAt } from '../web3/contract'; + +export class SftmxService { + constructor( + private readonly sftmxSubgraphService: SftmxSubgraphService, + private readonly stakingContractAddress: string, + ) {} + + public async getWithdrawalRequests(user: string): Promise { + const balances = await prisma.prismaSftmxWithdrawalRequest.findMany({ + where: { + user: user, + }, + }); + return balances; + } + + public async getStakingData(): Promise { + const stakingData = await prisma.prismaSftmxStakingData.findUniqueOrThrow({ + where: { id: this.stakingContractAddress }, + }); + return { + totalFtmAmountInPool: stakingData.totalFtmInPool, + numberOfVaults: stakingData.numberOfVaults, + totalFtmAmountStaked: stakingData.totalFtmStaked, + totalFtmAmount: stakingData.totalFtm, + maxDepositLimit: stakingData.maxDepositLimit, + minDepositLimit: stakingData.minDepositLimit, + maintenancePaused: stakingData.maintenancePaused, + undelegatePaused: stakingData.undelegatePaused, + withdrawPaused: stakingData.withdrawPaused, + stakingApr: stakingData.stakingApr, + exchangeRate: stakingData.exchangeRate, + withdrawalDelay: stakingData.withdrawalDelay, + }; + } + + public async syncStakingData() { + const multicaller = new Multicaller3(FTMStaking.abi); + multicaller.call('currentVaultCount', this.stakingContractAddress, 'currentVaultCount'); + multicaller.call('poolBalance', this.stakingContractAddress, 'getPoolBalance'); + multicaller.call('totalFtm', this.stakingContractAddress, 'totalFTMWorth'); + multicaller.call('maxDeposit', this.stakingContractAddress, 'maxDeposit'); + multicaller.call('minDeposit', this.stakingContractAddress, 'minDeposit'); + multicaller.call('maintenancePaused', this.stakingContractAddress, 'maintenancePaused'); + multicaller.call('undelegatePaused', this.stakingContractAddress, 'undelegatePaused'); + multicaller.call('withdrawPaused', this.stakingContractAddress, 'withdrawPaused'); + multicaller.call('getExchangeRate', this.stakingContractAddress, 'getExchangeRate'); + multicaller.call('withdrawalDelay', this.stakingContractAddress, 'withdrawalDelay'); + + const result = await multicaller.execute(); + + const vaultCount = result['currentVaultCount'] as BigNumber; + const poolBalance = result['poolBalance'] as BigNumber; + const totalFtm = result['totalFtm'] as BigNumber; + const maxDeposit = result['maxDeposit'] as BigNumber; + const minDeposit = result['minDeposit'] as BigNumber; + const exchangeRate = result['getExchangeRate'] as BigNumber; + const maintenancePaused = result['maintenancePaused'] as boolean; + const undelegatePaused = result['undelegatePaused'] as boolean; + const withdrawPaused = result['withdrawPaused'] as boolean; + const withdrawalDelay = result['withdrawalDelay'] as BigNumber; + + const stakingApr = await this.getStakingApr(); + + const stakingData = { + id: this.stakingContractAddress, + totalFtmStaked: formatFixed(totalFtm.sub(poolBalance).toString(), 18), + totalFtmInPool: formatFixed(poolBalance.toString(), 18), + numberOfVaults: parseFloat(vaultCount.toString()), + totalFtm: formatFixed(totalFtm.toString(), 18), + maxDepositLimit: formatFixed(maxDeposit.toString(), 18), + minDepositLimit: formatFixed(minDeposit.toString(), 18), + maintenancePaused: maintenancePaused, + undelegatePaused: undelegatePaused, + withdrawPaused: withdrawPaused, + stakingApr: stakingApr, + exchangeRate: formatFixed(exchangeRate.toString(), 18), + withdrawalDelay: parseFloat(withdrawalDelay.toString()), + }; + + await prisma.prismaSftmxStakingData.upsert({ + where: { id: this.stakingContractAddress }, + create: stakingData, + update: stakingData, + }); + } + + public async syncWithdrawalRequests() { + const allWithdrawalRequests = await this.sftmxSubgraphService.getAllWithdrawawlRequestsWithPaging(); + + const operations = []; + for (const request of allWithdrawalRequests) { + const requestData = { + id: request.id, + ftmStaking: this.stakingContractAddress, + user: request.user.id, + amountSftmx: request.amount, + isWithdrawn: request.isWithdrawn, + requestTimestamp: request.requestTime, + }; + operations.push( + prisma.prismaSftmxWithdrawalRequest.upsert({ + where: { id: requestData.id }, + create: requestData, + update: requestData, + }), + ); + } + await prismaBulkExecuteOperations(operations); + } + + private async getStakingApr(): Promise { + const baseApr = 0.018; + const maxLockApr = 0.06; + const validatorFee = 0.15; + const sftmxFee = 0.1; + const ftmStakingContract = getContractAt(this.stakingContractAddress, FTMStaking.abi); + + const totalFtm = (await ftmStakingContract.totalFTMWorth()) as BigNumber; + const poolFtm = (await ftmStakingContract.getPoolBalance()) as BigNumber; + const maturedVaultCount = await ftmStakingContract.getMaturedVaultLength(); + + let maturedFtmAmount = BigNumber.from('0'); + + for (let i = 0; i < maturedVaultCount; i++) { + const vaultAddress = await ftmStakingContract.getMaturedVault(i); + const vaultContract = getContractAt(vaultAddress, Vault.abi); + const vaultAmount = await vaultContract.currentStakeValue(); + maturedFtmAmount = maturedFtmAmount.add(vaultAmount); + } + + const totalFtmNum = parseFloat(formatFixed(totalFtm.toString(), 18)); + const poolFtmNum = parseFloat(formatFixed(poolFtm.toString(), 18)); + const maturedFtmNum = parseFloat(formatFixed(maturedFtmAmount.toString(), 18)); + const stakedFtmNum = totalFtmNum - poolFtmNum - maturedFtmNum; + + const totalMaxLockApr = (stakedFtmNum / totalFtmNum) * (maxLockApr * (1 - validatorFee)) * (1 - sftmxFee); + const totalBaseApr = (maturedFtmNum / totalFtmNum) * (baseApr * (1 - validatorFee)) * (1 - sftmxFee); + + return `${totalMaxLockApr + totalBaseApr}`; + } +} + +export const sftmxService = new SftmxService( + AllNetworkConfigsKeyedOnChain['FANTOM'].services.sftmxSubgraphService!, + AllNetworkConfigsKeyedOnChain['FANTOM'].data.sftmx!.stakingContractAddress, +); diff --git a/modules/subgraphs/sftmx-subgraph/sftmx-subgraph-queries.graphql b/modules/subgraphs/sftmx-subgraph/sftmx-subgraph-queries.graphql new file mode 100644 index 000000000..cf065e353 --- /dev/null +++ b/modules/subgraphs/sftmx-subgraph/sftmx-subgraph-queries.graphql @@ -0,0 +1,29 @@ +query WithdrawalRequests( + $skip: Int + $first: Int + $orderBy: WithdrawalRequest_orderBy + $orderDirection: OrderDirection + $where: WithdrawalRequest_filter + $block: Block_height +) { + withdrawalRequests( + skip: $skip + first: $first + orderBy: $orderBy + orderDirection: $orderDirection + where: $where + block: $block + ) { + ...WithdrawalRequest + } +} + +fragment WithdrawalRequest on WithdrawalRequest { + id + amount + isWithdrawn + requestTime + user { + id + } +} diff --git a/modules/subgraphs/sftmx-subgraph/sftmx.service.ts b/modules/subgraphs/sftmx-subgraph/sftmx.service.ts new file mode 100644 index 000000000..b5df11e5f --- /dev/null +++ b/modules/subgraphs/sftmx-subgraph/sftmx.service.ts @@ -0,0 +1,41 @@ +import { GraphQLClient } from 'graphql-request'; +import { + OrderDirection, + WithdrawalRequestFragment, + WithdrawalRequest_OrderBy, + getSdk, +} from './generated/sftmx-subgraph-types'; + +export class SftmxSubgraphService { + private sdk: ReturnType; + + constructor(subgraphUrl: string) { + this.sdk = getSdk(new GraphQLClient(subgraphUrl)); + } + + public async getAllWithdrawawlRequestsWithPaging(): Promise { + const limit = 1000; + let hasMore = true; + let withdrawalRequests: WithdrawalRequestFragment[] = []; + let id = '0'; + + while (hasMore) { + const response = await this.sdk.WithdrawalRequests({ + where: { id_gt: id }, + orderBy: WithdrawalRequest_OrderBy.id, + orderDirection: OrderDirection.asc, + first: limit, + }); + + withdrawalRequests = [...withdrawalRequests, ...response.withdrawalRequests]; + + if (response.withdrawalRequests.length < limit) { + hasMore = false; + } else { + id = response.withdrawalRequests[response.withdrawalRequests.length - 1].id; + } + } + + return withdrawalRequests; + } +} diff --git a/prisma/migrations/20231215083336_add_sftmx/migration.sql b/prisma/migrations/20231215083336_add_sftmx/migration.sql new file mode 100644 index 000000000..b43950d6d --- /dev/null +++ b/prisma/migrations/20231215083336_add_sftmx/migration.sql @@ -0,0 +1,32 @@ +-- CreateTable +CREATE TABLE "PrismaSftmxStakingData" ( + "id" TEXT NOT NULL, + "totalFtm" TEXT NOT NULL, + "totalFtmStaked" TEXT NOT NULL, + "totalFtmInPool" TEXT NOT NULL, + "numberOfVaults" INTEGER NOT NULL, + "stakingApr" TEXT NOT NULL, + "exchangeRate" TEXT NOT NULL, + "maxDepositLimit" TEXT NOT NULL, + "minDepositLimit" TEXT NOT NULL, + "withdrawalDelay" INTEGER NOT NULL, + "undelegatePaused" BOOLEAN NOT NULL, + "withdrawPaused" BOOLEAN NOT NULL, + "maintenancePaused" BOOLEAN NOT NULL, + + CONSTRAINT "PrismaSftmxStakingData_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "PrismaSftmxWithdrawalRequest" ( + "id" TEXT NOT NULL, + "user" TEXT NOT NULL, + "amountSftmx" TEXT NOT NULL, + "requestTimestamp" INTEGER NOT NULL, + "isWithdrawn" BOOLEAN NOT NULL, + + CONSTRAINT "PrismaSftmxWithdrawalRequest_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "PrismaSftmxWithdrawalRequest" ADD CONSTRAINT "PrismaSftmxWithdrawalRequest_id_fkey" FOREIGN KEY ("id") REFERENCES "PrismaSftmxStakingData"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f7c1d2cf3..211f2423f 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -617,6 +617,38 @@ model PrismaReliquaryTokenBalanceSnapshot { } + +model PrismaSftmxStakingData { + id String @id + totalFtm String + totalFtmStaked String + totalFtmInPool String + numberOfVaults Int + stakingApr String + exchangeRate String + + maxDepositLimit String + minDepositLimit String + withdrawalDelay Int + + undelegatePaused Boolean + withdrawPaused Boolean + maintenancePaused Boolean + + withdrawalRequests PrismaSftmxWithdrawalRequest[] +} + +model PrismaSftmxWithdrawalRequest { + id String @id + ftmStakingId PrismaSftmxStakingData @relation(fields:[id], references: [id]) + + user String + amountSftmx String + requestTimestamp Int + isWithdrawn Boolean +} + + model PrismaToken { @@id([address, chain]) diff --git a/worker/job-handlers.ts b/worker/job-handlers.ts index d2b3d2143..8329d69cd 100644 --- a/worker/job-handlers.ts +++ b/worker/job-handlers.ts @@ -16,6 +16,7 @@ import moment from 'moment'; import { cronsDurationMetricPublisher } from '../modules/metrics/cron-duration-metrics.client'; import { syncLatestFXPrices } from '../modules/token/latest-fx-price'; import { AllNetworkConfigs } from '../modules/network/network-config'; +import { sftmxService } from '../modules/sftmx/sftmx.service'; const runningJobs: Set = new Set(); @@ -294,6 +295,12 @@ export function configureWorkerRoutes(app: Express) { next, ); break; + case 'sync-sftmx-staking-data': + await runIfNotAlreadyRunning(job.name, chainId, () => sftmxService.syncStakingData(), res, next); + break; + case 'sync-sftmx-withdrawal-requests': + await runIfNotAlreadyRunning(job.name, chainId, () => sftmxService.syncWithdrawalRequests(), res, next); + break; default: res.sendStatus(400); throw new Error(`Unhandled job type ${job.name}`);