Overview
ETH Balance
ETH Value
$0.00Latest 25 from a total of 4,837 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Trade With Learn... | 11305914 | 1367 days ago | IN | 0 ETH | 0.000276625095 ETH | ||||
| Trade With Learn... | 11305482 | 1367 days ago | IN | 0.1818 ETH | 0.000309405219 ETH | ||||
| Trade With Learn... | 11305242 | 1367 days ago | IN | 0 ETH | 0.000276623979 ETH | ||||
| Trade With Learn... | 11305011 | 1367 days ago | IN | 0.1818 ETH | 0.000332713322 ETH | ||||
| Trade With Learn... | 11304678 | 1367 days ago | IN | 0 ETH | 0.00030195339 ETH | ||||
| Trade With Learn... | 11304499 | 1367 days ago | IN | 0 ETH | 0.000310562086 ETH | ||||
| Trade With Learn... | 11304359 | 1367 days ago | IN | 0.1818 ETH | 0.0003907531 ETH | ||||
| Trade With Learn... | 11304081 | 1367 days ago | IN | 0 ETH | 0.000277385178 ETH | ||||
| Trade With Learn... | 11303798 | 1367 days ago | IN | 0 ETH | 0.000277376249 ETH | ||||
| Trade Strategies... | 11303768 | 1367 days ago | IN | 0.1819 ETH | 0.00044950999 ETH | ||||
| Trade With Learn... | 11303437 | 1367 days ago | IN | 0 ETH | 0.00030082052 ETH | ||||
| Trade With Learn... | 11303270 | 1367 days ago | IN | 0.1821 ETH | 0.000329498873 ETH | ||||
| Trade With Learn... | 11302643 | 1367 days ago | IN | 0.0004 ETH | 0.00034211275 ETH | ||||
| Trade Strategies... | 11301283 | 1367 days ago | IN | 0 ETH | 0.000423002092 ETH | ||||
| Trade With Learn... | 11296495 | 1367 days ago | IN | 0.048 ETH | 0.000353890619 ETH | ||||
| Trade With Learn... | 11293727 | 1367 days ago | IN | 0 ETH | 0.000345205495 ETH | ||||
| Trade Weth To Et... | 11292405 | 1367 days ago | IN | 0 ETH | 0.000314407443 ETH | ||||
| Trade Eth To Wet... | 11292381 | 1367 days ago | IN | 0.001 ETH | 0.00033213808 ETH | ||||
| Trade With Learn... | 11286473 | 1367 days ago | IN | 0.98 ETH | 0.000396120224 ETH | ||||
| Trade With Learn... | 11286301 | 1367 days ago | IN | 0 ETH | 0.000363578729 ETH | ||||
| Trade With Learn... | 11285264 | 1367 days ago | IN | 0 ETH | 0.000393627942 ETH | ||||
| Trade With Learn... | 11276458 | 1367 days ago | IN | 0 ETH | 0.000447573883 ETH | ||||
| Trade With Learn... | 11270767 | 1368 days ago | IN | 0.05 ETH | 0.000348319449 ETH | ||||
| Trade With Learn... | 11266685 | 1368 days ago | IN | 0.005 ETH | 0.000441708926 ETH | ||||
| Trade Eth To Wet... | 11266430 | 1368 days ago | IN | 0.005 ETH | 0.000351027884 ETH |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 11305914 | 1367 days ago | 0.18117387 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0.1809927 ETH | ||||
| 11305914 | 1367 days ago | 0.00018117 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305914 | 1367 days ago | 0 ETH | ||||
| 11305482 | 1367 days ago | 0 ETH |
Cross-Chain Transactions
Contract Source Code (Solidity)
/**
*Submitted for verification at Arbiscan.io on 2021-09-14
*/
// SPDX-License-Identifier: MIT
// ((/*, ,*((/,.
// &&@@&&%#/*. .*(#&&@@@@%.
// &&@@@@@@@&%(. ,#%&@@@@@@@@%.
// &&@@@@@@@@@&&(, ,#&@@@@@@@@@@@%.
// &&@@@@@@@@@@@&&/. .(&&@@@@@@@@@@@@%.
// %&@@@@@@@@@@@@@&(, *#&@@@@@@@@@@@@@@%.
// #&@@@@@@@@@@@@@@&#* .*#@@@@@@@@@@@@@@@&#.
// #&@@@@@@@@@@@@@@@@#. ,%&@@@@@@@@@@@@@@@&#.
// #&@@@@@@@@@@@@@@@@%(, ,(&@@@@@@@@@@@@@@@@&#.
// #&@@@@@@@@@@@@@@@@&&/ .(%&@@@@@@@@@@@@@@@@&#.
// #%@@@@@@@@@@@@@@@@@@(. ,(/,. .#&@@@@@@@@@@@@@@@@@&#.
// (%@@@@@@@@@@@@@@@@@@#*. ./%&&&/. .*%@@@@@@@@@@@@@@@@@@%(.
// (%@@@@@@@@@@@@@@@@@@#*. *#&@@@@&%*. .*%@@@@@@@@@@@@@@@@@@%(.
// (%@@@@@@@@@@@@@@@@@@#/. ./#@@@@@@@@%(. ./%@@@@@@@@@@@@@@@@@@%(.
// (%@@@@@@@@@@@@@@@@@@#/. ./&@@@@@@@@@@&(* ,/%@@@@@@@@@@@@@@@@@@%(.
// (%@@@@@@@@@@@@@@@@@@%/. ,#&@@@@@@@@@@@@&#,. ,/%@@@@@@@@@@@@@@@@@@%(.
// /%@@@@@@@@@@@@@@@@@@#/. *(&@@@@@@@@@@@@@@&&* ./%@@@@@@@@@@@@@@@@@&%(.
// /%@@@@@@@@@@@@@@@@@@#/. .(&@@@@@@@@@@@@@@@@@#*. ,/%@@@@@@@@@@@@@@@@@&#/.
// ,#@@@@@@@@@@@@@@@@@@#/. ./%@@@@@@@@@@@@@@@@@@&#, ,/%@@@@@@@@@@@@@@@@@&(,
// /%&@@@@@@@@@@@@@@@@#/. *#&@@@@@@@@@@@@@@@@@@@&* ,/%@@@@@@@@@@@@@@@@&%*
// .*#&@@@@@@@@@@@@@@@#/. /&&@@@@@@@@@@@@@@@@@@@&/. ,/%@@@@@@@@@@@@@@@@#*.
// ,(&@@@@@@@@@@@@@@#/. /@@@@@@@@@@@@@@@@@@@@@&(, ,/%@@@@@@@@@@@@@@%(,
// .*(&&@@@@@@@@@@@#/. /&&@@@@@@@@@@@@@@@@@@@&/, ,/%@@@@@@@@@@@&%/,
// ./%&@@@@@@@@@#/. *#&@@@@@@@@@@@@@@@@@@@%* ,/%@@@@@@@@@&%*
// ,/#%&&@@@@#/. ,#&@@@@@@@@@@@@@@@@@#/. ,/%@@@@&&%(/,
// ./#&@@%/. ,/&@@@@@@@@@@@@@@%(, ,/%@@%#*.
// .,,, ,/%&@@@@@@@@&%(* .,,,.
// ,/%&@@@%(*.
// .,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,**((/*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
//
//
pragma solidity ^0.8.0;
/** @title Precompiled contract that exists in every Arbitrum chain at 0x0000000000000000000000000000000000000066.
* Allows registering / retrieving addresses at uint indices, saving calldata.
*/
interface IArbAddressTable {
/**
* @notice Register an address in the address table
* @param addr address to register
* @return index of the address (existing index, or newly created index if not already registered)
*/
function register(address addr) external returns(uint);
/**
* @param addr address to lookup
* @return index of an address in the address table (revert if address isn't in the table)
*/
function lookup(address addr) external view returns(uint);
/**
* @notice Check whether an address exists in the address table
* @param addr address to check for presence in table
* @return true if address is in table
*/
function addressExists(address addr) external view returns(bool);
/**
* @return size of address table (= first unused index)
*/
function size() external view returns(uint);
/**
* @param index index to lookup address
* @return address at a given index in address table (revert if index is beyond end of table)
*/
function lookupIndex(uint index) external view returns(address);
/**
* @notice read a compressed address from a bytes buffer
* @param buf bytes buffer containing an address
* @param offset offset of target address
* @return resulting address and updated offset into the buffer (revert if buffer is too short)
*/
function decompress(bytes calldata buf, uint offset) external pure returns(address, uint);
/**
* @notice compress an address and return the result
* @param addr address to compress
* @return compressed address bytes
*/
function compress(address addr) external returns(bytes memory);
}
// File: library/byte/BytesLib.sol
// MODIFIED VERSION FROM https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol
pragma solidity >=0.8.0 <0.9.0;
library BytesLib {
function concat(
bytes memory _preBytes,
bytes memory _postBytes
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
assembly {
// Read the first 32 bytes of _preBytes storage, which is the length
// of the array. (We don't need to use the offset into the slot
// because arrays use the entire slot.)
let fslot := sload(_preBytes.slot)
// Arrays of 31 bytes or less have an even value in their slot,
// while longer arrays have an odd value. The actual length is
// the slot divided by two for odd values, and the lowest order
// byte divided by two for even values.
// If the slot is even, bitwise and the slot with 255 and divide by
// two to get the length. If the slot is odd, bitwise and the slot
// with -1 and divide by two.
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
let newlength := add(slength, mlength)
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
switch add(lt(slength, 32), lt(newlength, 32))
case 2 {
// Since the new array still fits in the slot, we just need to
// update the contents of the slot.
// uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
sstore(
_preBytes.slot,
// all the modifications to the slot are inside this
// next block
add(
// we can just add to the slot contents because the
// bytes we want to change are the LSBs
fslot,
add(
mul(
div(
// load the bytes from memory
mload(add(_postBytes, 0x20)),
// zero all bytes to the right
exp(0x100, sub(32, mlength))
),
// and now shift left the number of bytes to
// leave space for the length in the slot
exp(0x100, sub(32, newlength))
),
// increase length by the double of the memory
// bytes length
mul(mlength, 2)
)
)
)
}
case 1 {
// The stored value fits in the slot, but the combined value
// will exceed it.
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// The contents of the _postBytes array start 32 bytes into
// the structure. Our first read should obtain the `submod`
// bytes that can fit into the unused space in the last word
// of the stored array. To get this, we read 32 bytes starting
// from `submod`, so the data we read overlaps with the array
// contents by `submod` bytes. Masking the lowest-order
// `submod` bytes allows us to add that value directly to the
// stored value.
let submod := sub(32, slength)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(
sc,
add(
and(
fslot,
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
),
and(mload(mc), mask)
)
)
for {
mc := add(mc, 0x20)
sc := add(sc, 1)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
default {
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
// Start copying to the last used word of the stored array.
let sc := add(keccak256(0x0, 0x20), div(slength, 32))
// save new length
sstore(_preBytes.slot, add(mul(newlength, 2), 1))
// Copy over the first `submod` bytes of the new data as in
// case 1 above.
let slengthmod := mod(slength, 32)
let mlengthmod := mod(mlength, 32)
let submod := sub(32, slengthmod)
let mc := add(_postBytes, submod)
let end := add(_postBytes, mlength)
let mask := sub(exp(0x100, submod), 1)
sstore(sc, add(sload(sc), and(mload(mc), mask)))
for {
sc := add(sc, 1)
mc := add(mc, 0x20)
} lt(mc, end) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
sstore(sc, mload(mc))
}
mask := exp(0x100, sub(mc, end))
sstore(sc, mul(div(mload(mc), mask), mask))
}
}
}
function slice(
bytes memory _bytes,
uint256 _start,
uint256 _length
)
internal
pure
returns (bytes memory)
{
require(_length + 31 >= _length, "slice_overflow");
require(_bytes.length >= _start + _length, "slice_outOfBounds");
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
//zero out the 32 bytes slice we are about to return
//we need to do it because Solidity does not garbage collect
mstore(tempBytes, 0)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
uint16 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x2), _start))
}
return tempUint;
}
function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) {
require(_bytes.length >= _start + 3, "toUint24_outOfBounds");
uint24 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x3), _start))
}
return tempUint;
}
function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
uint32 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x4), _start))
}
return tempUint;
}
function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
uint64 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x8), _start))
}
return tempUint;
}
function toUint80(bytes memory _bytes, uint256 _start) internal pure returns (uint80) {
require(_bytes.length >= _start + 10, "toUint80_outOfBounds");
uint80 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xa), _start))
}
return tempUint;
}
function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
uint96 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xc), _start))
}
return tempUint;
}
function toUint112(bytes memory _bytes, uint256 _start) internal pure returns (uint112) {
require(_bytes.length >= _start + 14, "toUint112_outOfBounds");
uint112 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0xe), _start))
}
return tempUint;
}
function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
uint128 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x10), _start))
}
return tempUint;
}
function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
uint256 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
bytes32 tempBytes32;
assembly {
tempBytes32 := mload(add(add(_bytes, 0x20), _start))
}
return tempBytes32;
}
function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
bool success = true;
assembly {
let length := mload(_preBytes)
// if lengths don't match the arrays are not equal
switch eq(length, mload(_postBytes))
case 1 {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
let mc := add(_preBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
} eq(add(lt(mc, end), cb), 2) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// if any of these checks fails then arrays are not equal
if iszero(eq(mload(mc), mload(cc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
function equalStorage(
bytes storage _preBytes,
bytes memory _postBytes
)
internal
view
returns (bool)
{
bool success = true;
assembly {
// we know _preBytes_offset is 0
let fslot := sload(_preBytes.slot)
// Decode the length of the stored array like in concatStorage().
let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
let mlength := mload(_postBytes)
// if lengths don't match the arrays are not equal
switch eq(slength, mlength)
case 1 {
// slength can contain both the length and contents of the array
// if length < 32 bytes so let's prepare for that
// v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
if iszero(iszero(slength)) {
switch lt(slength, 32)
case 1 {
// blank the last byte which is the length
fslot := mul(div(fslot, 0x100), 0x100)
if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
// unsuccess:
success := 0
}
}
default {
// cb is a circuit breaker in the for loop since there's
// no said feature for inline assembly loops
// cb = 1 - don't breaker
// cb = 0 - break
let cb := 1
// get the keccak hash to get the contents of the array
mstore(0x0, _preBytes.slot)
let sc := keccak256(0x0, 0x20)
let mc := add(_postBytes, 0x20)
let end := add(mc, mlength)
// the next line is the loop condition:
// while(uint256(mc < end) + cb == 2)
for {} eq(add(lt(mc, end), cb), 2) {
sc := add(sc, 1)
mc := add(mc, 0x20)
} {
if iszero(eq(sload(sc), mload(mc))) {
// unsuccess:
success := 0
cb := 0
}
}
}
}
}
default {
// unsuccess:
success := 0
}
}
return success;
}
}
// File: wx/libraries/WardenDataDeserialize.sol
// License: BSD-3-Clause
// Copyright 2021 Wardenswap.finance.
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pragma solidity ^0.8.0;
contract WardenDataDeserialize {
using BytesLib for bytes;
IArbAddressTable internal immutable addressTable;
constructor(
IArbAddressTable _addressTable
) {
addressTable = _addressTable;
}
function toBytes(bytes32 _data) private pure returns (bytes memory) {
return abi.encodePacked(_data);
}
function _decodeCompressed(
bytes memory _data,
uint256 _cursor,
bool skipLearnedId
)
private
pure
returns(
uint256 _srcIndex, // 24-bit, 16,777,216 possible
uint256 _destIndex, // 24-bit, 16,777,216 possible
uint256 _srcAmount, // 96-bit, 79,228,162,514 (18 decimals)
uint256 _minDestAmount, // 96-bit, 79,228,162,514 (18 decimals)
uint256 _learnedId, // 16-bit, 65,536 possible
uint256 _newCursor
)
{
// Example
// 0x000001000002FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
// 0x000001000002000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFF
// 0x0000010000020000007CAEE97613E670000100000000B469471F801400021123
// uint256: _srcIndex 1
// uint256: _destIndex 2
// uint256: _srcAmount 2300000000000000000001
// uint256: _minDestAmount 13000000000000000002
// uint256: _learnedId 4387
// uint256: _newCursor 32
_srcIndex = _data.toUint24(_cursor);
_cursor += 3;
_destIndex = _data.toUint24(_cursor);
_cursor += 3;
_srcAmount = _data.toUint96(_cursor);
_cursor += 12;
_minDestAmount = _data.toUint96(_cursor);
_cursor += 12;
if (!skipLearnedId) {
_learnedId = _data.toUint16(_cursor);
_cursor += 2;
}
_newCursor = _cursor;
}
function decodeCompressed1(
bytes32 _data
)
public
view
returns (
address _src,
address _dest,
uint256 _srcAmount,
uint256 _minDestAmount,
uint256 _learnedId
)
{
bytes memory data = toBytes(_data);
uint256 srcIndex;
uint256 destIndex;
(
srcIndex,
destIndex,
_srcAmount,
_minDestAmount,
_learnedId,
) = _decodeCompressed(data, 0, false);
// tokenLookup
_src = addressTable.lookupIndex(srcIndex);
_dest = addressTable.lookupIndex(destIndex);
}
function decodeCompressed2(
bytes memory _data,
uint256 _cursor
)
public
view
returns (
address _src,
address _dest,
uint256 _srcAmount,
uint256 _minDestAmount,
uint256 _newCursor
)
{
uint256 srcIndex;
uint256 destIndex;
(
srcIndex,
destIndex,
_srcAmount,
_minDestAmount,
,
_newCursor
) = _decodeCompressed(_data, _cursor, true);
// tokenLookup
_src = addressTable.lookupIndex(srcIndex);
_dest = addressTable.lookupIndex(destIndex);
}
function _decodeSrcMinAmountsLearnedId(
bytes memory _data,
uint256 _cursor,
bool skipLearnedId
)
private
pure
returns (
uint256 _srcAmount,
uint256 _minDestAmount,
uint256 _learnedId,
uint256 _newCursor
)
{
// 8-bit insructions
// 2-bit for srcAmount insruction
// 2-bit for minDestAmount insruction
// 1-bit for learnedId insruction
// Example
// instructions: 00010101
// _data: 15 10000000000000000001 10000000000000000002 100001
// _data: 0x151000000000000000000110000000000000000002100001
//
// instructions: 00001100
// _data: 0C 1000000000000001 1000000000000000000000000001 1001
// _data: 0x0C100000000000000110000000000000000000000000011001
//
// instructions: 00001100
// skipLearnedId: true
// _data: 0C 1000000000000001 1000000000000000000000000001
// _data: 0x0C10000000000000011000000000000000000000000001
uint8 instructions = _data.toUint8(_cursor);
_cursor += 1;
uint8 srcAmountInstruction = instructions & 0x03;
instructions = instructions >> 2;
(_srcAmount, _cursor) = _decodeAmount(srcAmountInstruction, _data, _cursor);
uint8 minDestAmountInstruction = instructions & 0x03;
instructions = instructions >> 2;
(_minDestAmount, _cursor) = _decodeAmount(minDestAmountInstruction, _data, _cursor);
if (!skipLearnedId) {
uint8 learnedIdInstruction = instructions & 0x01;
instructions = instructions >> 1;
(_learnedId, _cursor) = _decodeLearnedId(learnedIdInstruction, _data, _cursor);
}
_newCursor = _cursor;
}
function decodeSrcMinAmountsLearnedId(
bytes memory _data,
uint256 _cursor
)
public
pure
returns (
uint256 _srcAmount,
uint256 _minDestAmount,
uint256 _learnedId,
uint256 _newCursor
)
{
(
_srcAmount,
_minDestAmount,
_learnedId,
_newCursor
) = _decodeSrcMinAmountsLearnedId(_data, _cursor, false);
}
function decodeSrcMinAmounts(
bytes memory _data,
uint256 _cursor
)
public
pure
returns (
uint256 _srcAmount,
uint256 _minDestAmount,
uint256 _newCursor
)
{
(
_srcAmount,
_minDestAmount,
,
_newCursor
) = _decodeSrcMinAmountsLearnedId(_data, _cursor, true);
}
function decodeSubRoutesAndCorrespondentTokens(
bytes memory _data,
uint256 _cursor
)
public
view
returns (
uint256[] memory _subRoutes, // 16-bit, 65,536 possible
IERC20[] memory _correspondentTokens,
uint256 _newCursor
)
{
// 8-bit insructions
// 6-bit route length, 64 possible
// 2-bit token instruction
// Example
//
// 0x010001 [1]
// 0x8200010002000001 [1,2], [token(1)]
// 0x431001200130010000000100000002 [4097,8193,12289] [token(1), token(2)]
//
// instructions: 00000001
// _data: 01 1001
// _data: 0x011001
//
// instructions: 10000010
// _data: 82 0001 0002 000001
// _data: 0x8200010002000001
//
// instructions: 01000011
// _data: 43 1001 2001 3001 00000001 00000002
// _data: 0x431001200130010000000100000002
//
// instructions: 00000011
// _data: 03 0002 0003 0004 c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
// _data: 0x03000200030004c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
uint8 instructions = _data.toUint8(_cursor);
_cursor += 1;
uint256 routeLength = instructions & 0x3F;
instructions = instructions >> 6;
uint8 tokenInstruction = instructions & 0x03;
instructions = instructions >> 2;
_subRoutes = new uint256[](routeLength);
_correspondentTokens = new IERC20[](routeLength - 1);
for (uint256 i = 0; i < routeLength; i++) {
_subRoutes[i] = _data.toUint16(_cursor);
_cursor += 2;
}
for (uint256 i = 0; i < routeLength - 1; i++) {
address token;
(token, _cursor) = _lookupAddress(tokenInstruction, _data, _cursor);
_correspondentTokens[i] = IERC20(token);
}
_newCursor = _cursor;
}
function decodeLearnedIdsAndVolumns(
bytes memory _data,
uint256 _cursor
)
public
pure
returns (
uint256[] memory _learnedIds,
uint256[] memory _volumns, // 8-bit, 256 possible
uint256 _newCursor
)
{
// 8-bit insructions
// 6-bit split length, 64 possible
// 1-bit learned id instruction
// Example
// instructions: 00000010
// _data: 02 1003 2004 3C
// _data: 0x02100320043C
//
// instructions: 01000011
// _data: 43 100003 200004 300005 1E 19
// _data: 0x431000032000043000051E19
uint8 instructions = _data.toUint8(_cursor);
_cursor += 1;
uint256 splitLength = instructions & 0x3F;
instructions = instructions >> 6;
uint8 learnedIdInstruction = instructions & 0x01;
instructions = instructions >> 1;
// Decode learn ids
_learnedIds = new uint256[](splitLength);
for (uint256 i = 0; i < splitLength; i++) {
(_learnedIds[i], _cursor) = _decodeLearnedId(learnedIdInstruction, _data, _cursor);
}
// Each volumn has 8-bit
_volumns = new uint256[](splitLength);
uint256 volumnRemain = 100;
for (uint256 i = 0; i < splitLength - 1; i++) {
_volumns[i] = _data.toUint8(_cursor);
_cursor += 1;
volumnRemain -= _volumns[i];
}
_volumns[splitLength - 1] = volumnRemain;
_newCursor = _cursor;
}
function _lookupAddress(
uint8 _instruction, // 2-bit instruction
bytes memory _data,
uint256 _cursor
)
private
view
returns (
address _address,
uint256 _newCursor
)
{
// Example
// instruction: 0
// _data: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
//
// instruction: 1
// _data: 0x00000001
//
// instruction: 2
// _data: 0x000001
//
// instruction: 3
// _data: 0x
if (_instruction == 0) { // not registered
_address = _data.toAddress(_cursor);
_newCursor = _cursor + 20;
} else if (_instruction == 1) { // registered (32-bit)
_address = addressTable.lookupIndex(_data.toUint32(_cursor));
_newCursor = _cursor + 4;
} else if (_instruction == 2) { // registered (24-bit)
_address = addressTable.lookupIndex(_data.toUint24(_cursor));
_newCursor = _cursor + 3;
} else if (_instruction == 3) { // skip
_address = 0x0000000000000000000000000000000000000000;
_newCursor = _cursor;
} else {
revert("WardenDataDeserialize:_lookupAddress bad instruction");
}
}
function lookupSrcDestReceiverAddresses(
bytes memory _data,
uint256 _cursor
)
public
view
returns (
address _src,
address _dest,
address _receiver,
uint256 _newCursor
)
{
// 8-bit insructions
// 2-bit for _src insruction
// 2-bit for _dest insruction
// 2-bit for _receiver insruction
// Example
// instructions: 00111001
// _data: 39 00000001 000003
// _data: 0x3900000001000003
//
// instructions: 00001000
// _data: 08 c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 000004 5e12Ae8e436Cd25F0041d931f8E4c7a3bB42cc1F
// _data: 0x08c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000045e12Ae8e436Cd25F0041d931f8E4c7a3bB42cc1F
//
// instructions: 00110001
// _data: 31 00000003 2260fac5e5542a773aa44fbcfedf7c193bc2c599
// _data: 0x31000000032260fac5e5542a773aa44fbcfedf7c193bc2c599
//
uint8 instructions = _data.toUint8(_cursor);
_cursor += 1;
uint8 srcInstruction = instructions & 0x03;
instructions = instructions >> 2;
uint8 destInstruction = instructions & 0x03;
instructions = instructions >> 2;
uint8 receiverInstruction = instructions & 0x03;
instructions = instructions >> 2;
(_src, _cursor) = _lookupAddress(srcInstruction, _data, _cursor);
(_dest, _cursor) = _lookupAddress(destInstruction, _data, _cursor);
(_receiver, _cursor) = _lookupAddress(receiverInstruction, _data, _cursor);
_newCursor = _cursor;
}
function _decodeAmount(
uint8 _instruction, // 2-bit instruction
bytes memory _data,
uint256 _cursor
)
private
pure
returns (
uint256 _amount,
uint256 _newCursor
)
{
// Example
// instruction: 0
// _data: 0x1000000000000001
//
// instruction: 1
// _data: 0x10000000000000000001
//
// instruction: 2
// _data: 0x100000000000000000000001
//
// instruction: 3
// _data: 0x1000000000000000000000000001
if (_instruction == 0) { // 64-bit, 18 (denominated in 1e18)
_amount = _data.toUint64(_cursor);
_newCursor = _cursor + 8;
} else if (_instruction == 1) { // 80-bit, 1.2m (denominated in 1e18)
_amount = _data.toUint80(_cursor);
_newCursor = _cursor + 10;
} else if (_instruction == 2) { // 96-bit, 79.2b (denominated in 1e18)
_amount = _data.toUint96(_cursor);
_newCursor = _cursor + 12;
} else if (_instruction == 3) { // 112-bit, 5,192mm (denominated in 1e18)
_amount = _data.toUint112(_cursor);
_newCursor = _cursor + 14;
} else {
revert("WardenDataDeserialize:_decodeAmount bad instruction");
}
}
function _decodeLearnedId(
uint8 _instruction, // 1-bit instruction
bytes memory _data,
uint256 _cursor
)
private
pure
returns (
uint256 _learnedId,
uint256 _newCursor
)
{
// Example
// instruction: 0
// _data: 0x1001
//
// instruction: 1
// _data: 0x100001
if (_instruction == 0) { // 16-bit, 65,536 possible
_learnedId = _data.toUint16(_cursor);
_newCursor = _cursor + 2;
} else if (_instruction == 1) { // 24-bit, 16,777,216 possible
_learnedId = _data.toUint24(_cursor);
_newCursor = _cursor + 3;
} else {
revert("WardenDataDeserialize:_decodeLearnedId bad instruction");
}
}
}
// File: wx/interface/IWardenPostTrade.sol
// License: MIT
pragma solidity ^0.8.0;
interface IWardenPostTrade {
function postTradeAndFee(
IERC20 _src,
IERC20 _dest,
uint256 _srcAmount,
uint256 _destAmount,
address _trader,
address _receiver,
bool _isSplit
)
external
returns (
uint256 _fee,
address _collector
);
}
// File: wx/libraries/IWETH.sol
pragma solidity ^0.8.0;
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}
// File: wx/interface/IWardenCosmicBrainForL2.sol
pragma solidity ^0.8.0;
interface IWardenCosmicBrain {
function train(
uint256[] calldata _subRoutes,
IERC20[] calldata _correspondentTokens
)
external
returns (uint256 _learnedId);
function trainTradingPair(
IERC20 _src,
IERC20 _dest,
uint256 _srcAmount,
uint256 _destAmount,
uint256 _learnedId
)
external
returns (bool _isAlreadyLearned);
function learnedHashes(
uint256 _learnedId
)
external
view
returns (bytes32);
function fetchRoutesAndTokens(
bytes32 _learnedHash
)
external
view
returns (
uint256[] memory _subRoutes,
IERC20[] memory _correspondentTokens
);
function hasLearned(
bytes32 _learnedHash
)
external
view
returns (bool);
function learnedIds(
bytes32 _learnedHash
)
external
view
returns (uint256);
function learnedRoutesLength(
bytes32 _learnedHash
)
external
view
returns (uint256);
}
// File: wx/libraries/IWardenTradingRoute0_8.sol
pragma solidity ^0.8.0;
/**
* @title Warden Trading Route
* @dev The Warden trading route interface has an standard functions and event
* for other smart contract to implement to join Warden Swap as Market Maker.
*/
interface IWardenTradingRoute {
/**
* @dev when new trade occure (and success), this event will be boardcast.
* @param _src Source token
* @param _srcAmount amount of source tokens
* @param _dest Destination token
* @param _destAmount: amount of actual destination tokens
*/
event Trade(
IERC20 indexed _src,
uint256 _srcAmount,
IERC20 indexed _dest,
uint256 _destAmount
);
/**
* @notice use token address 0xeee...eee for ether
* @dev makes a trade between src and dest token
* @param _src Source token
* @param _dest Destination token
* @param _srcAmount amount of source tokens
** @return _destAmount: amount of actual destination tokens
*/
function trade(
IERC20 _src,
IERC20 _dest,
uint256 _srcAmount,
address receiver
)
external
payable
returns(uint256 _destAmount);
/**
* @dev provide destinationm token amount for given source amount
* @param _src Source token
* @param _dest Destination token
* @param _srcAmount Amount of source tokens
** @return _destAmount: amount of expected destination tokens
*/
function getDestinationReturnAmount(
IERC20 _src,
IERC20 _dest,
uint256 _srcAmount
)
external
returns(uint256 _destAmount);
function getDepositAddress(
IERC20 _src,
IERC20 _dest
)
external
view
returns(address _target);
}
// File: wx/interface/IWardenCosmoCore0_8.sol
pragma solidity ^0.8.0;
interface IWardenCosmoCore {
/**
* @dev Struct of trading route
* @param name Name of trading route.
* @param enable The flag of trading route to check is trading route enable.
* @param route The address of trading route.
*/
struct Route {
string name;
bool enable;
IWardenTradingRoute route;
}
event AddedTradingRoute(
address indexed addedBy,
string name,
IWardenTradingRoute indexed routingAddress,
uint256 indexed index
);
event UpdatedTradingRoute(
address indexed updatedBy,
string name,
IWardenTradingRoute indexed routingAddress,
uint256 indexed index
);
event EnabledTradingRoute(
address indexed enabledBy,
string name,
IWardenTradingRoute indexed routingAddress,
uint256 indexed index
);
event DisabledTradingRoute(
address indexed disabledBy,
string name,
IWardenTradingRoute indexed routingAddress,
uint256 indexed index
);
function tradingRoutes(uint256 _index) external view returns (Route memory);
function allRoutesLength() external view returns (uint256);
function isTradingRouteEnabled(uint256 _index) external view returns (bool);
}
// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/utils/Address.sol
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) private pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/token/ERC20/IERC20.sol
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/token/ERC20/utils/SafeERC20.sol
pragma solidity ^0.8.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/utils/Context.sol
pragma solidity ^0.8.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/access/Ownable.sol
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_setOwner(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/security/ReentrancyGuard.sol
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
// File: wx/WardenSwap1_5_L2.sol
pragma solidity ^0.8.0;
contract WardenSwap1_5_Aegis is Ownable, ReentrancyGuard {
using SafeERC20 for IERC20;
IWardenCosmoCore public cosmoCore;
IWardenCosmicBrain public cosmicBrain;
IWardenPostTrade public postTrade;
IWETH private immutable weth;
IERC20 private constant ETHER_ERC20 = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
event UpdatedWardenCosmoCore(
IWardenCosmoCore indexed cosmoCore
);
event UpdatedWardenCosmicBrain(
IWardenCosmicBrain indexed cosmicBrain
);
event UpdatedWardenPostTrade(
IWardenPostTrade indexed postTrade
);
/**
* @dev when new trade occur (and success), this event will be boardcast.
* @param srcAsset Source token
* @param srcAmount amount of source token
* @param destAsset Destination token
* @param destAmount amount of destination token
* @param trader user address
*/
event Trade(
address indexed srcAsset, // Source
uint256 srcAmount,
address indexed destAsset, // Destination
uint256 destAmount,
address indexed trader, // User
address receiver, // User / Merchant
bool cacheHit,
bool hasSplitted
);
event CollectFee(
IERC20 indexed token,
address indexed wallet,
uint256 amount
);
constructor(
IWardenCosmoCore _cosmoCore,
IWardenCosmicBrain _cosmicBrain,
IWardenPostTrade _postTrade,
IWETH _weth
) {
cosmoCore = _cosmoCore;
cosmicBrain = _cosmicBrain;
postTrade = _postTrade;
weth = _weth;
emit UpdatedWardenCosmoCore(_cosmoCore);
emit UpdatedWardenCosmicBrain(_cosmicBrain);
emit UpdatedWardenPostTrade(_postTrade);
}
function updateRoutingManagement(
IWardenCosmoCore _cosmoCore
)
external
onlyOwner
{
cosmoCore = _cosmoCore;
emit UpdatedWardenCosmoCore(_cosmoCore);
}
function updateWardenLearner(
IWardenCosmicBrain _cosmicBrain
)
external
onlyOwner
{
cosmicBrain = _cosmicBrain;
emit UpdatedWardenCosmicBrain(_cosmicBrain);
}
function updateWardenPostTrade(
IWardenPostTrade _postTrade
)
external
onlyOwner
{
postTrade = _postTrade;
emit UpdatedWardenPostTrade(_postTrade);
}
/**
* @dev makes a trade between token to token by tradingRouteIndex
* @param tradingRouteIndex index of trading route
* @param src Source token
* @param srcAmount amount of source tokens
* @param dest Destination token
* @param fromAddress address of trader
* @param toAddress destination address
* @return amount of actual destination tokens
*/
function _tradeTokenToToken(
uint256 tradingRouteIndex,
IERC20 src,
uint256 srcAmount,
IERC20 dest,
address fromAddress,
address toAddress
)
private
returns(uint256)
{
// Load trading route
IWardenTradingRoute tradingRoute = cosmoCore.tradingRoutes(tradingRouteIndex).route;
// Deposit to target
address depositAddress = tradingRoute.getDepositAddress(src, dest);
if (fromAddress == address(this)) {
src.safeTransfer(depositAddress, srcAmount);
} else if (fromAddress != 0x0000000000000000000000000000000000000000) {
src.safeTransferFrom(fromAddress, depositAddress, srcAmount);
}
// Trade to route
uint256 destAmount = tradingRoute.trade(
src,
dest,
srcAmount,
toAddress
);
return destAmount;
}
function _tradeStrategies(
IERC20 _src,
uint256 _srcAmount,
IERC20 _dest,
uint256[] memory _subRoutes,
IERC20[] memory _correspondentTokens,
address _fromAddress
)
private
returns(uint256 _destAmount)
{
IERC20 src;
IERC20 dest;
_destAmount = _srcAmount;
uint256 routersLen = _subRoutes.length;
for (uint i = 0; i < routersLen; i++) {
src = i == 0 ? _src : _correspondentTokens[i - 1];
dest = i == routersLen - 1 ? _dest : _correspondentTokens[i];
uint256 routeIndex = _subRoutes[i];
address fromAddress = i == 0 ? _fromAddress : 0x0000000000000000000000000000000000000000;
address toAddress;
// Advanced fetching next market address
if (i == routersLen - 1) {
toAddress = address(this);
} else {
IWardenTradingRoute tradingRoute = cosmoCore.tradingRoutes(_subRoutes[i + 1]).route;
IERC20 nextDest = i + 1 == routersLen - 1 ? _dest : _correspondentTokens[i + 1];
toAddress = tradingRoute.getDepositAddress(dest, nextDest);
}
_destAmount = _tradeTokenToToken(routeIndex, src, _destAmount, dest, fromAddress, toAddress);
}
}
/**
* @dev makes a trade by providing trading strategy
* @param _src Source token
* @param _srcAmount amount of source tokens
* @param _dest Destination token
* @param _minDestAmount minimum of destination token amount
* @param _subRoutes trading routers
* @param _correspondentTokens intermediate tokens
* @param _receiver receiver address
* @param _learnedId previous learning id
* @return _destAmount amount of actual destination tokens
*/
function _tradeStrategiesWithSafeGuard(
IERC20 _src,
uint256 _srcAmount,
IERC20 _dest,
uint256 _minDestAmount,
uint256[] memory _subRoutes,
IERC20[] memory _correspondentTokens,
address _receiver,
uint256 _learnedId
)
private
returns(uint256 _destAmount)
{
require(_subRoutes.length - 1 == _correspondentTokens.length, "WardenSwap: routes and tokens length mismatched");
{
IERC20 adjustedSrc;
IERC20 adjustedDest = ETHER_ERC20 == _dest ? IERC20(address(weth)) : _dest;
address fromAddress;
// Wrap ETH
if (ETHER_ERC20 == _src) {
require(msg.value == _srcAmount, "WardenSwap: Ether source amount mismatched");
weth.deposit{value: _srcAmount}();
adjustedSrc = IERC20(address(weth));
fromAddress = address(this);
} else {
adjustedSrc = _src;
fromAddress = msg.sender;
}
// Record src/dest asset for later consistency check.
uint256 srcAmountBefore = adjustedSrc.balanceOf(fromAddress);
uint256 destAmountBefore = adjustedDest.balanceOf(address(this));
_destAmount = _tradeStrategies(
adjustedSrc,
_srcAmount,
adjustedDest,
_subRoutes,
_correspondentTokens,
fromAddress
);
// Sanity check
// Recheck if src/dest amount correct
require(adjustedSrc.balanceOf(fromAddress) == srcAmountBefore - _srcAmount, "WardenSwap: source amount mismatched after trade");
require(adjustedDest.balanceOf(address(this)) == destAmountBefore + _destAmount, "WardenSwap: destination amount mismatched after trade");
}
// Unwrap ETH
if (ETHER_ERC20 == _dest) {
weth.withdraw(_destAmount);
}
// Collect fee
_destAmount = _postTradeAndCollectFee(
_src,
_dest,
_srcAmount,
_destAmount,
msg.sender,
_receiver,
false
);
// Throw exception if destination amount doesn't meet user requirement.
require(_destAmount >= _minDestAmount, "WardenSwap: destination amount is too low.");
if (ETHER_ERC20 == _dest) {
(bool success, ) = _receiver.call{value: _destAmount}(""); // Send back ether to sender
require(success, "WardenSwap: Transfer ether back to caller failed.");
} else { // Send back token to sender
_dest.safeTransfer(_receiver, _destAmount);
}
uint256 learnedId = _learnedId;
if (0 == _learnedId) {
learnedId = cosmicBrain.train(_subRoutes, _correspondentTokens);
}
cosmicBrain.trainTradingPair(
_src,
_dest,
_srcAmount,
_destAmount,
learnedId
);
emit Trade(address(_src), _srcAmount, address(_dest), _destAmount, msg.sender, _receiver, 0 != _learnedId, false);
}
/**
* @dev makes a trade by providing trading strategy
* @param _src Source token
* @param _srcAmount amount of source tokens
* @param _dest Destination token
* @param _minDestAmount minimum of destination token amount
* @param _subRoutes trading routers
* @param _correspondentTokens intermediate tokens
* @param _receiver receiver address
* @return _destAmount amount of actual destination tokens
*/
function tradeStrategies(
IERC20 _src,
uint256 _srcAmount,
IERC20 _dest,
uint256 _minDestAmount,
uint256[] memory _subRoutes,
IERC20[] memory _correspondentTokens,
address _receiver
)
public
payable
nonReentrant
returns(uint256 _destAmount)
{
_destAmount = _tradeStrategiesWithSafeGuard(
_src,
_srcAmount,
_dest,
_minDestAmount,
_subRoutes,
_correspondentTokens,
_receiver,
0
);
}
/**
* @dev makes a trade by providing learned id
* @param _src Source token
* @param _srcAmount amount of source tokens
* @param _dest Destination token
* @param _minDestAmount minimum of destination token amount
* @param _learnedId unique id
* @param _receiver receiver address
* @return _destAmount amount of actual destination tokens
*/
function tradeWithLearned(
IERC20 _src,
uint256 _srcAmount,
IERC20 _dest,
uint256 _minDestAmount,
uint256 _learnedId,
address _receiver
)
public
payable
nonReentrant
returns(uint256 _destAmount)
{
bytes32 learnedHash = cosmicBrain.learnedHashes(_learnedId);
(
uint256[] memory subRoutes,
IERC20[] memory correspondentTokens
) = cosmicBrain.fetchRoutesAndTokens(learnedHash);
_destAmount = _tradeStrategiesWithSafeGuard(
_src,
_srcAmount,
_dest,
_minDestAmount,
subRoutes,
correspondentTokens,
_receiver,
_learnedId
);
}
function _split2(
uint256[] memory _learnedIds,
uint256[] memory _volumns,
IERC20 _src,
uint256 _totalSrcAmount,
IERC20 _dest,
address _fromAddress
)
private
returns (
uint256 _destAmount
)
{
// Trade with routes
uint256 amountRemain = _totalSrcAmount;
for (uint i = 0; i < _learnedIds.length; i++) {
uint256 amountForThisRound;
if (i == _learnedIds.length - 1) {
amountForThisRound = amountRemain;
} else {
amountForThisRound = _totalSrcAmount * _volumns[i] / 100;
amountRemain = amountRemain - amountForThisRound;
}
bytes32 learnedHash = cosmicBrain.learnedHashes(_learnedIds[i]);
(
uint256[] memory subRoutes,
IERC20[] memory correspondentTokens
) = cosmicBrain.fetchRoutesAndTokens(learnedHash);
_destAmount = _destAmount +
_tradeStrategies(
_src,
amountForThisRound,
_dest,
subRoutes,
correspondentTokens,
_fromAddress
)
;
}
}
function _splitTradesWithSafeGuard(
uint256[] memory _learnedIds,
uint256[] memory _volumns,
IERC20 _src,
uint256 _totalSrcAmount,
IERC20 _dest
)
private
returns(uint256 _destAmount)
{
IERC20 adjustedSrc;
IERC20 adjustedDest = ETHER_ERC20 == _dest ? IERC20(address(weth)) : _dest;
address fromAddress;
// Wrap ETH
if (ETHER_ERC20 == _src) {
require(msg.value == _totalSrcAmount, "WardenSwap: Ether source amount mismatched");
weth.deposit{value: _totalSrcAmount}();
adjustedSrc = IERC20(address(weth));
fromAddress = address(this);
} else {
adjustedSrc = _src;
fromAddress = msg.sender;
}
// Record src/dest asset for later consistency check.
uint256 srcAmountBefore = adjustedSrc.balanceOf(fromAddress);
uint256 destAmountBefore = adjustedDest.balanceOf(address(this));
_destAmount = _split2(
_learnedIds,
_volumns,
adjustedSrc,
_totalSrcAmount,
adjustedDest,
fromAddress
);
// Sanity check
// Recheck if src/dest amount correct
require(adjustedSrc.balanceOf(fromAddress) == srcAmountBefore - _totalSrcAmount, "WardenSwap: source amount mismatched after trade");
require(adjustedDest.balanceOf(address(this)) == destAmountBefore + _destAmount, "WardenSwap: destination amount mismatched after trade");
// Unwrap ETH
if (ETHER_ERC20 == _dest) {
weth.withdraw(_destAmount);
}
}
/**
* @dev makes a trade by splitting volumes
* @param _learnedIds unique ids
* @param _volumns volume percentages
* @param _src Source token
* @param _totalSrcAmount amount of source tokens
* @param _dest Destination token
* @param _minDestAmount minimum of destination token amount
* @param _receiver receiver address
* @return _destAmount amount of actual destination tokens
*/
function splitTrades(
uint256[] memory _learnedIds,
uint256[] memory _volumns,
IERC20 _src,
uint256 _totalSrcAmount,
IERC20 _dest,
uint256 _minDestAmount,
address _receiver
)
public
payable
nonReentrant
returns(uint256 _destAmount)
{
require(_learnedIds.length > 0, "WardenSwap: learnedIds can not be empty");
require(_learnedIds.length == _volumns.length, "WardenSwap: learnedIds and volumns lengths mismatched");
_destAmount = _splitTradesWithSafeGuard(
_learnedIds,
_volumns,
_src,
_totalSrcAmount,
_dest
);
// Collect fee
_destAmount = _postTradeAndCollectFee(
_src,
_dest,
_totalSrcAmount,
_destAmount,
msg.sender,
_receiver,
true
);
// Throw exception if destination amount doesn't meet user requirement.
require(_destAmount >= _minDestAmount, "WardenSwap: destination amount is too low.");
if (ETHER_ERC20 == _dest) {
(bool success, ) = _receiver.call{value: _destAmount}(""); // Send back ether to sender
require(success, "WardenSwap: Transfer ether back to caller failed.");
} else { // Send back token to sender
_dest.safeTransfer(_receiver, _destAmount);
}
emit Trade(address(_src), _totalSrcAmount, address(_dest), _destAmount, msg.sender, _receiver, true, true);
}
/**
* @dev makes a trade ETH -> WETH
* @param _receiver receiver address
* @return _destAmount amount of actual destination tokens
*/
function tradeEthToWeth(
address _receiver
)
external
payable
nonReentrant
returns(uint256 _destAmount)
{
weth.deposit{value: msg.value}();
IERC20(address(weth)).safeTransfer(_receiver, msg.value);
_destAmount = msg.value;
emit Trade(address(ETHER_ERC20), msg.value, address(weth), _destAmount, msg.sender, _receiver, false, false);
}
/**
* @dev makes a trade WETH -> ETH
* @param _srcAmount amount of source tokens
* @param _receiver receiver address
* @return _destAmount amount of actual destination tokens
*/
function tradeWethToEth(
uint256 _srcAmount,
address _receiver
)
external
nonReentrant
returns(uint256 _destAmount)
{
IERC20(address(weth)).safeTransferFrom(msg.sender, address(this), _srcAmount);
weth.withdraw(_srcAmount);
(bool success, ) = _receiver.call{value: _srcAmount}(""); // Send back ether to sender
require(success, "WardenSwap: Transfer ether back to caller failed.");
_destAmount = _srcAmount;
emit Trade(address(weth), _srcAmount, address(ETHER_ERC20), _destAmount, msg.sender, _receiver, false, false);
}
// In case of an expected and unexpected event that has some token amounts remain in this contract, owner can call to collect them.
function collectRemainingToken(
IERC20 _token,
uint256 _amount
)
external
onlyOwner
{
_token.safeTransfer(msg.sender, _amount);
}
// In case of an expected and unexpected event that has some ether amounts remain in this contract, owner can call to collect them.
function collectRemainingEther(
uint256 _amount
)
external
onlyOwner
{
(bool success, ) = msg.sender.call{value: _amount}(""); // Send back ether to sender
require(success, "WardenSwap: Transfer ether back to caller failed.");
}
// Receive ETH in case of trade Token -> ETH
receive() external payable {}
function _postTradeAndCollectFee(
IERC20 _src,
IERC20 _dest,
uint256 _srcAmount,
uint256 _destAmount,
address _trader,
address _receiver,
bool _isSplit
)
private
returns (uint256 _newDestAmount)
{
// Collect fee
(uint256 fee, address feeWallet) = postTrade.postTradeAndFee(
_src,
_dest,
_srcAmount,
_destAmount,
_trader,
_receiver,
_isSplit
);
if (fee > 0) {
_collectFee(
_dest,
fee,
feeWallet
);
}
return _destAmount - fee;
}
function _collectFee(
IERC20 _token,
uint256 _fee,
address _feeWallet
)
private
{
if (ETHER_ERC20 == _token) {
(bool success, ) = payable(_feeWallet).call{value: _fee}(""); // Send back ether to sender
require(success, "Transfer fee of ether failed.");
} else {
_token.safeTransfer(_feeWallet, _fee);
}
emit CollectFee(_token, _feeWallet, _fee);
}
}
///////////////////////////
// Optimized for Layer 2 //
///////////////////////////
contract WardenSwap1_5_Aegis_L2 is WardenSwap1_5_Aegis, WardenDataDeserialize {
using BytesLib for bytes;
constructor(
IWardenCosmoCore _cosmoCore,
IWardenCosmicBrain _cosmicBrain,
IWardenPostTrade _postTrade,
IWETH _weth,
IArbAddressTable _addressTable
)
WardenSwap1_5_Aegis(
_cosmoCore,
_cosmicBrain,
_postTrade,
_weth
)
WardenDataDeserialize(_addressTable)
{
}
function decodeAddresses(
bytes memory _data,
uint256 _cursor
)
public
view
returns (
address _src,
address _dest,
address _receiver,
uint256 _newCursor
)
{
(
_src,
_dest,
_receiver,
_newCursor
) = lookupSrcDestReceiverAddresses(_data, _cursor);
if (_receiver == 0x0000000000000000000000000000000000000000) {
_receiver = msg.sender;
}
}
function tradeStrategiesC1(
bytes memory _data
)
external
payable
returns (uint256 _destAmount)
{
uint256 cursor = 0;
address src;
address dest;
uint256 srcAmount;
uint256 minDestAmount;
(
src,
dest,
srcAmount,
minDestAmount,
cursor
) = decodeCompressed2(_data, cursor);
uint256[] memory subRoutes;
IERC20[] memory correspondentTokens;
(
subRoutes,
correspondentTokens,
cursor
) = decodeSubRoutesAndCorrespondentTokens(_data, cursor);
return tradeStrategies(
IERC20(src),
srcAmount,
IERC20(dest),
minDestAmount,
subRoutes,
correspondentTokens,
msg.sender
);
}
function tradeStrategiesC2(
bytes memory _data
)
external
payable
returns(uint256 _destAmount)
{
uint256 cursor = 0;
// Addresses
address src;
address dest;
address receiver;
(
src,
dest,
receiver,
cursor
) = decodeAddresses(_data, cursor);
// Amounts
uint256 srcAmount;
uint256 minDestAmount;
(
srcAmount,
minDestAmount,
cursor
) = decodeSrcMinAmounts(_data, cursor);
// Routes, Tokens
uint256[] memory subRoutes;
IERC20[] memory correspondentTokens;
(
subRoutes,
correspondentTokens,
cursor
) = decodeSubRoutesAndCorrespondentTokens(_data, cursor);
return tradeStrategies(
IERC20(src),
srcAmount,
IERC20(dest),
minDestAmount,
subRoutes,
correspondentTokens,
receiver
);
}
function tradeStrategiesC3(
bytes memory _data
)
external
payable
returns(uint256 _destAmount)
{
uint256 cursor = 0;
address src;
address dest;
address receiver;
(
src,
dest,
receiver,
cursor
) = decodeAddresses(_data, cursor);
uint256 srcAmount = _data.toUint256(cursor);
cursor += 32;
uint256 minDestAmount = _data.toUint256(cursor);
cursor += 32;
// Routes, Tokens
uint256[] memory subRoutes;
IERC20[] memory correspondentTokens;
(
subRoutes,
correspondentTokens,
cursor
) = decodeSubRoutesAndCorrespondentTokens(_data, cursor);
return tradeStrategies(
IERC20(src),
srcAmount,
IERC20(dest),
minDestAmount,
subRoutes,
correspondentTokens,
receiver
);
}
function tradeWithLearnedC1(
bytes32 _compressedData
)
external
payable
returns(uint256 _destAmount)
{
(
address src,
address dest,
uint256 srcAmount,
uint256 minDestAmount,
uint256 learnedId
) = decodeCompressed1(_compressedData);
return tradeWithLearned(
IERC20(src),
srcAmount,
IERC20(dest),
minDestAmount,
learnedId,
msg.sender
);
}
function tradeWithLearnedC2(
bytes memory _data
)
external
payable
returns(uint256 _destAmount)
{
uint256 cursor = 0;
// Addresses
address src;
address dest;
address receiver;
(
src,
dest,
receiver,
cursor
) = decodeAddresses(_data, cursor);
// Amounts
uint256 srcAmount;
uint256 minDestAmount;
uint256 learnedId;
(
srcAmount,
minDestAmount,
learnedId,
cursor
) = decodeSrcMinAmountsLearnedId(_data, cursor);
return tradeWithLearned(
IERC20(src),
srcAmount,
IERC20(dest),
minDestAmount,
learnedId,
receiver
);
}
function tradeWithLearnedC3(
bytes memory _data
)
external
payable
returns(uint256 _destAmount)
{
uint256 cursor = 0;
address src;
address dest;
address receiver;
(
src,
dest,
receiver,
cursor
) = decodeAddresses(_data, cursor);
uint256 srcAmount = _data.toUint256(cursor);
cursor += 32;
uint256 minDestAmount = _data.toUint256(cursor);
cursor += 32;
uint256 learnedId = _data.toUint256(cursor);
cursor += 32;
return tradeWithLearned(
IERC20(src),
srcAmount,
IERC20(dest),
minDestAmount,
learnedId,
receiver
);
}
function splitTradesC1(
bytes memory _data
)
external
payable
returns(uint256 _destAmount)
{
uint256 cursor = 0;
address src;
address dest;
uint256 totalSrcAmount;
uint256 minDestAmount;
(
src,
dest,
totalSrcAmount,
minDestAmount,
cursor
) = decodeCompressed2(_data, cursor);
// Learned ids, volumns
uint256[] memory learnedIds;
uint256[] memory volumns;
(
learnedIds,
volumns,
cursor
) = decodeLearnedIdsAndVolumns(_data, cursor);
return splitTrades(
learnedIds,
volumns,
IERC20(src),
totalSrcAmount,
IERC20(dest),
minDestAmount,
msg.sender
);
}
function splitTradesC2(
bytes memory _data
)
external
payable
returns(uint256 _destAmount)
{
uint256 cursor = 0;
// Addresses
address src;
address dest;
address receiver;
(
src,
dest,
receiver,
cursor
) = decodeAddresses(_data, cursor);
// Amounts
uint256 totalSrcAmount;
uint256 minDestAmount;
(
totalSrcAmount,
minDestAmount,
cursor
) = decodeSrcMinAmounts(_data, cursor);
// Learned ids, volumns
uint256[] memory learnedIds;
uint256[] memory volumns;
(
learnedIds,
volumns,
cursor
) = decodeLearnedIdsAndVolumns(_data, cursor);
return splitTrades(
learnedIds,
volumns,
IERC20(src),
totalSrcAmount,
IERC20(dest),
minDestAmount,
receiver
);
}
function splitTradesC3(
bytes memory _data
)
external
payable
returns(uint256 _destAmount)
{
uint256 cursor = 0;
address src;
address dest;
address receiver;
(
src,
dest,
receiver,
cursor
) = decodeAddresses(_data, cursor);
uint256 totalSrcAmount = _data.toUint256(cursor);
cursor += 32;
uint256 minDestAmount = _data.toUint256(cursor);
cursor += 32;
// Learned ids, volumns
uint256[] memory learnedIds;
uint256[] memory volumns;
(
learnedIds,
volumns,
cursor
) = decodeLearnedIdsAndVolumns(_data, cursor);
return splitTrades(
learnedIds,
volumns,
IERC20(src),
totalSrcAmount,
IERC20(dest),
minDestAmount,
receiver
);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IWardenCosmoCore","name":"_cosmoCore","type":"address"},{"internalType":"contract IWardenCosmicBrain","name":"_cosmicBrain","type":"address"},{"internalType":"contract IWardenPostTrade","name":"_postTrade","type":"address"},{"internalType":"contract IWETH","name":"_weth","type":"address"},{"internalType":"contract IArbAddressTable","name":"_addressTable","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"CollectFee","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":"srcAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"srcAmount","type":"uint256"},{"indexed":true,"internalType":"address","name":"destAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"destAmount","type":"uint256"},{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"bool","name":"cacheHit","type":"bool"},{"indexed":false,"internalType":"bool","name":"hasSplitted","type":"bool"}],"name":"Trade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IWardenCosmicBrain","name":"cosmicBrain","type":"address"}],"name":"UpdatedWardenCosmicBrain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IWardenCosmoCore","name":"cosmoCore","type":"address"}],"name":"UpdatedWardenCosmoCore","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IWardenPostTrade","name":"postTrade","type":"address"}],"name":"UpdatedWardenPostTrade","type":"event"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"collectRemainingEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"collectRemainingToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cosmicBrain","outputs":[{"internalType":"contract IWardenCosmicBrain","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cosmoCore","outputs":[{"internalType":"contract IWardenCosmoCore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_cursor","type":"uint256"}],"name":"decodeAddresses","outputs":[{"internalType":"address","name":"_src","type":"address"},{"internalType":"address","name":"_dest","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_newCursor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_data","type":"bytes32"}],"name":"decodeCompressed1","outputs":[{"internalType":"address","name":"_src","type":"address"},{"internalType":"address","name":"_dest","type":"address"},{"internalType":"uint256","name":"_srcAmount","type":"uint256"},{"internalType":"uint256","name":"_minDestAmount","type":"uint256"},{"internalType":"uint256","name":"_learnedId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_cursor","type":"uint256"}],"name":"decodeCompressed2","outputs":[{"internalType":"address","name":"_src","type":"address"},{"internalType":"address","name":"_dest","type":"address"},{"internalType":"uint256","name":"_srcAmount","type":"uint256"},{"internalType":"uint256","name":"_minDestAmount","type":"uint256"},{"internalType":"uint256","name":"_newCursor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_cursor","type":"uint256"}],"name":"decodeLearnedIdsAndVolumns","outputs":[{"internalType":"uint256[]","name":"_learnedIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_volumns","type":"uint256[]"},{"internalType":"uint256","name":"_newCursor","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_cursor","type":"uint256"}],"name":"decodeSrcMinAmounts","outputs":[{"internalType":"uint256","name":"_srcAmount","type":"uint256"},{"internalType":"uint256","name":"_minDestAmount","type":"uint256"},{"internalType":"uint256","name":"_newCursor","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_cursor","type":"uint256"}],"name":"decodeSrcMinAmountsLearnedId","outputs":[{"internalType":"uint256","name":"_srcAmount","type":"uint256"},{"internalType":"uint256","name":"_minDestAmount","type":"uint256"},{"internalType":"uint256","name":"_learnedId","type":"uint256"},{"internalType":"uint256","name":"_newCursor","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_cursor","type":"uint256"}],"name":"decodeSubRoutesAndCorrespondentTokens","outputs":[{"internalType":"uint256[]","name":"_subRoutes","type":"uint256[]"},{"internalType":"contract IERC20[]","name":"_correspondentTokens","type":"address[]"},{"internalType":"uint256","name":"_newCursor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_cursor","type":"uint256"}],"name":"lookupSrcDestReceiverAddresses","outputs":[{"internalType":"address","name":"_src","type":"address"},{"internalType":"address","name":"_dest","type":"address"},{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_newCursor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"postTrade","outputs":[{"internalType":"contract IWardenPostTrade","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_learnedIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_volumns","type":"uint256[]"},{"internalType":"contract IERC20","name":"_src","type":"address"},{"internalType":"uint256","name":"_totalSrcAmount","type":"uint256"},{"internalType":"contract IERC20","name":"_dest","type":"address"},{"internalType":"uint256","name":"_minDestAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"splitTrades","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"splitTradesC1","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"splitTradesC2","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"splitTradesC3","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"tradeEthToWeth","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_src","type":"address"},{"internalType":"uint256","name":"_srcAmount","type":"uint256"},{"internalType":"contract IERC20","name":"_dest","type":"address"},{"internalType":"uint256","name":"_minDestAmount","type":"uint256"},{"internalType":"uint256[]","name":"_subRoutes","type":"uint256[]"},{"internalType":"contract IERC20[]","name":"_correspondentTokens","type":"address[]"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"tradeStrategies","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"tradeStrategiesC1","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"tradeStrategiesC2","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"tradeStrategiesC3","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_srcAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"tradeWethToEth","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_src","type":"address"},{"internalType":"uint256","name":"_srcAmount","type":"uint256"},{"internalType":"contract IERC20","name":"_dest","type":"address"},{"internalType":"uint256","name":"_minDestAmount","type":"uint256"},{"internalType":"uint256","name":"_learnedId","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"tradeWithLearned","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_compressedData","type":"bytes32"}],"name":"tradeWithLearnedC1","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"tradeWithLearnedC2","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"tradeWithLearnedC3","outputs":[{"internalType":"uint256","name":"_destAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IWardenCosmoCore","name":"_cosmoCore","type":"address"}],"name":"updateRoutingManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IWardenCosmicBrain","name":"_cosmicBrain","type":"address"}],"name":"updateWardenLearner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IWardenPostTrade","name":"_postTrade","type":"address"}],"name":"updateWardenPostTrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c06040523480156200001157600080fd5b506040516200490138038062004901833981016040819052620000349162000196565b8085858585620000443362000146565b60018055600280546001600160a01b038087166001600160a01b031992831681179093556003805487831690841617905560048054918616919092161790556001600160601b0319606083901b166080526040517fa524ebbfbe21120240da574f40225bd07c7ac918927b018a847e29319cb7e14790600090a26040516001600160a01b038416907fb9471cba7e6c6e177386e0b3e0a38c3414efdf1a9a5f199755b2dc979ad4ecd890600090a26040516001600160a01b038316907ff3809f73f1bea6bcad288beb0538a25e1b98b4388cc422d087050ff52f7cbf8790600090a25050505060601b6001600160601b03191660a052506200022f9350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080600080600060a08688031215620001af57600080fd5b8551620001bc8162000216565b6020870151909550620001cf8162000216565b6040870151909450620001e28162000216565b6060870151909350620001f58162000216565b6080870151909250620002088162000216565b809150509295509295909350565b6001600160a01b03811681146200022c57600080fd5b50565b60805160601c60a05160601c614628620002d9600039600081816111ea01528181611285015281816117ca0152818161186601528181611aea0152611bb1015260008181610d5301528181610d9101528181610e8f01528181611497015281816115150152818161154f01528181611d9201528181611df601528181611e6a0152818161212501528181612461015281816124c501528181612539015261280201526146286000f3fe6080604052600436106101825760003560e01c806310b8e70f1461018e57806312d3a396146101b0578063199d34cf146101e8578063278203ba1461022357806327d2f16c1461027857806332cc1c5d146102a557806335689011146102c65780633ca58a01146102d95780634912dd14146102ec5780634cf6455b1461030c5780634f7919dd1461031f57806350c57d1d1461033f5780635a5e959c14610352578063613f8bbe146103655780636293263914610378578063629e14251461038b57806366f7c956146103ab5780636d16ecee146103cb578063715018a6146103eb57806378fc6db0146104005780637ab3e6451461041357806381d22e9a146104535780638da5cb5b146104665780638f64d73a1461047b57806397f8b0961461049b578063bc0488fa146104bb578063c292fc1b146104db578063c8a7c7e51461050c578063dca489e01461051f578063e77040f414610532578063eaeff54914610561578063f13a9ad814610581578063f2fde38b1461059457600080fd5b3661018957005b600080fd5b34801561019a57600080fd5b506101ae6101a9366004613af8565b6105b4565b005b3480156101bc57600080fd5b506101d06101cb366004613d2d565b610636565b6040516101df93929190614134565b60405180910390f35b3480156101f457600080fd5b50610208610203366004613d2d565b6107c1565b604080519384526020840192909252908201526060016101df565b34801561022f57600080fd5b5061024361023e366004613d2d565b6107e1565b6040516101df94939291906001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b34801561028457600080fd5b50600454610298906001600160a01b031681565b6040516101df91906140c1565b6102b86102b3366004613cf1565b610852565b6040519081526020016101df565b6102b86102d4366004613bf4565b6108b0565b6102b86102e7366004613cbf565b610aef565b3480156102f857600080fd5b506101ae610307366004613d71565b610b24565b6102b861031a366004613cf1565b610b6b565b34801561032b57600080fd5b50600254610298906001600160a01b031681565b6102b861034d366004613cf1565b610bf0565b6102b8610360366004613cf1565b610c30565b6102b8610373366004613cf1565b610c80565b6102b8610386366004613cf1565b610cc0565b34801561039757600080fd5b506102b86103a6366004613fdc565b610d1c565b3480156103b757600080fd5b506101ae6103c6366004613af8565b610ef0565b3480156103d757600080fd5b506101ae6103e6366004613af8565b610f69565b3480156103f757600080fd5b506101ae610fe2565b6102b861040e366004613d9d565b61101d565b34801561041f57600080fd5b5061043361042e366004613d2d565b611068565b6040805194855260208501939093529183015260608201526080016101df565b6102b8610461366004613cf1565b61108a565b34801561047257600080fd5b506102986110c8565b34801561048757600080fd5b506101ae610496366004613cbf565b6110d7565b3480156104a757600080fd5b50600354610298906001600160a01b031681565b3480156104c757600080fd5b506102436104d6366004613d2d565b61116e565b3480156104e757600080fd5b506104fb6104f6366004613cbf565b6111a3565b6040516101df9594939291906140d5565b6102b861051a366004613eaf565b611315565b6102b861052d366004613af8565b611468565b34801561053e57600080fd5b5061055261054d366004613d2d565b6115c6565b6040516101df9392919061416a565b34801561056d57600080fd5b506104fb61057c366004613d2d565b61178e565b6102b861058f366004613cf1565b6118f6565b3480156105a057600080fd5b506101ae6105af366004613af8565b611952565b336105bd6110c8565b6001600160a01b0316146105ec5760405162461bcd60e51b81526004016105e390614311565b60405180910390fd5b600480546001600160a01b0319166001600160a01b0383169081179091556040517ff3809f73f1bea6bcad288beb0538a25e1b98b4388cc422d087050ff52f7cbf8790600090a250565b60608060008061064686866119f2565b90506106536001866144a4565b9450600090603f81169060061c600316816001600160401b0381111561067b5761067b614587565b6040519080825280602002602001820160405280156106a4578160200160208202803683370190505b5095506106b26001836144fd565b6001600160401b038111156106c9576106c9614587565b6040519080825280602002602001820160405280156106f2578160200160208202803683370190505b50945060005b8281101561074a5761070a8989611a4e565b61ffff1687828151811061072057610720614571565b60209081029190910101526107366002896144a4565b97508061074281614540565b9150506106f8565b5060005b6107596001846144fd565b8110156107b357600061076d838b8b611aab565b809a5081925050508087838151811061078857610788614571565b6001600160a01b039092166020928302919091019091015250806107ab81614540565b91505061074e565b508693505050509250925092565b60008060006107d285856001611ce4565b92989197509195509350505050565b6000808080806107f187876119f2565b90506107fe6001876144a4565b95506003600682901c81169181811691600282901c81169160041c16610825838b8b611aab565b99509750610834828b8b611aab565b99509650610843818b8b611aab565b989b979a509850505050505050565b600080808080610862868261116e565b96509194509250905060008061087888876107c1565b9750909250905060608061088c8a89610636565b995090925090506108a28785888686868b61101d565b9a9950505050505050505050565b6000600260015414156108d55760405162461bcd60e51b81526004016105e39061439b565b600260015587516109385760405162461bcd60e51b815260206004820152602760248201527f57617264656e537761703a206c6561726e65644964732063616e206e6f7420626044820152666520656d70747960c81b60648201526084016105e3565b86518851146109a75760405162461bcd60e51b815260206004820152603560248201527f57617264656e537761703a206c6561726e656449647320616e6420766f6c756d6044820152741b9cc81b195b99dd1a1cc81b5a5cdb585d18da1959605a1b60648201526084016105e3565b6109b48888888888611d68565b90506109c68685878433876001612198565b9050828110156109e85760405162461bcd60e51b81526004016105e3906142c7565b6000805160206145d38339815191526001600160a01b0385161415610a80576000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610a54576040519150601f19603f3d011682016040523d82523d6000602084013e610a59565b606091505b5050905080610a7a5760405162461bcd60e51b81526004016105e390614276565b50610a94565b610a946001600160a01b038516838361226d565b336001600160a01b0316846001600160a01b0316876001600160a01b03166000805160206145b3833981519152888587600180604051610ad89594939291906143d2565b60405180910390a460018055979650505050505050565b600080600080600080610b01876111a3565b94509450945094509450610b19858486858533611315565b979650505050505050565b33610b2d6110c8565b6001600160a01b031614610b535760405162461bcd60e51b81526004016105e390614311565b610b676001600160a01b038316338361226d565b5050565b600080808080610b7b868261116e565b9650919450925090506000610b9087866122d5565b9050610b9d6020866144a4565b94506000610bab88876122d5565b9050610bb86020876144a4565b95506000610bc689886122d5565b9050610bd36020886144a4565b9650610be3868487858589611315565b9998505050505050505050565b60008080808080610c01878261178e565b985092965090945092509050606080610c1a89886115c6565b98509092509050610be3828288878988336108b0565b600080808080610c40868261116e565b965091945092509050600080610c5688876107c1565b97509092509050606080610c6a8a896115c6565b995090925090506108a2828289878a888b6108b0565b60008080808080610c91878261178e565b985092965090945092509050606080610caa8988610636565b98509092509050610be38685878686863361101d565b600080808080610cd0868261116e565b9650919450925090506000610ce587866122d5565b9050610cf26020866144a4565b94506000610d0088876122d5565b9050610d0d6020876144a4565b9550606080610c6a8a896115c6565b600060026001541415610d415760405162461bcd60e51b81526004016105e39061439b565b6002600155610d7b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333086612333565b604051632e1a7d4d60e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015610ddd57600080fd5b505af1158015610df1573d6000803e3d6000fd5b505050506000826001600160a01b03168460405160006040518083038185875af1925050503d8060008114610e42576040519150601f19603f3d011682016040523d82523d6000602084013e610e47565b606091505b5050905080610e685760405162461bcd60e51b81526004016105e390614276565b839150336001600160a01b03166000805160206145d38339815191526001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166000805160206145b3833981519152878688600080604051610edd9594939291906143d2565b60405180910390a4506001805592915050565b33610ef96110c8565b6001600160a01b031614610f1f5760405162461bcd60e51b81526004016105e390614311565b600380546001600160a01b0319166001600160a01b0383169081179091556040517fb9471cba7e6c6e177386e0b3e0a38c3414efdf1a9a5f199755b2dc979ad4ecd890600090a250565b33610f726110c8565b6001600160a01b031614610f985760405162461bcd60e51b81526004016105e390614311565b600280546001600160a01b0319166001600160a01b0383169081179091556040517fa524ebbfbe21120240da574f40225bd07c7ac918927b018a847e29319cb7e14790600090a250565b33610feb6110c8565b6001600160a01b0316146110115760405162461bcd60e51b81526004016105e390614311565b61101b6000612371565b565b6000600260015414156110425760405162461bcd60e51b81526004016105e39061439b565b60026001556110588888888888888860006123c1565b6001805598975050505050505050565b60008060008061107a86866000611ce4565b9299919850965090945092505050565b60008080808061109a868261116e565b965091945092509050600080806110b18988611068565b995091945092509050610be3868487858589611315565b6000546001600160a01b031690565b336110e06110c8565b6001600160a01b0316146111065760405162461bcd60e51b81526004016105e390614311565b604051600090339083908381818185875af1925050503d8060008114611148576040519150601f19603f3d011682016040523d82523d6000602084013e61114d565b606091505b5050905080610b675760405162461bcd60e51b81526004016105e390614276565b60008060008061117e86866107e1565b929650909450925090506001600160a01b03821661119a573391505b92959194509250565b6000806000806000806111b587612aba565b90506000806111c683600080612ae5565b506040516311430cf160e31b815260048101869052929a50909850965091935091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638a1867889060240160206040518083038186803b15801561123457600080fd5b505afa158015611248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126c9190613b15565b6040516311430cf160e31b8152600481018390529098507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638a1867889060240160206040518083038186803b1580156112cf57600080fd5b505afa1580156112e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113079190613b15565b965050505091939590929450565b60006002600154141561133a5760405162461bcd60e51b81526004016105e39061439b565b600260015560035460405163972f414360e01b8152600481018590526000916001600160a01b03169063972f41439060240160206040518083038186803b15801561138457600080fd5b505afa158015611398573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bc9190613cd8565b60035460405163345c341560e21b81526004810183905291925060009182916001600160a01b03169063d170d0549060240160006040518083038186803b15801561140657600080fd5b505afa15801561141a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114429190810190613b32565b915091506114568a8a8a8a86868b8d6123c1565b600180559a9950505050505050505050565b60006002600154141561148d5760405162461bcd60e51b81526004016105e39061439b565b60026001819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156114f057600080fd5b505af1158015611504573d6000803e3d6000fd5b506115409350506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691508490503461226d565b349050336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166000805160206145d38339815191526001600160a01b03166000805160206145b38339815191523485876000806040516115b59594939291906143d2565b60405180910390a460018055919050565b6060806000806115d686866119f2565b90506115e36001866144a4565b94506001600782901c811691603f81169160069190911c16816001600160401b0381111561161357611613614587565b60405190808252806020026020018201604052801561163c578160200160208202803683370190505b50955060005b8281101561168a57611655828a8a612b9d565b88838151811061166757611667614571565b60200260200101819a50828152505050808061168290614540565b915050611642565b50816001600160401b038111156116a3576116a3614587565b6040519080825280602002602001820160405280156116cc578160200160208202803683370190505b509450606460005b6116df6001856144fd565b811015611756576116f08a8a6119f2565b60ff1687828151811061170557611705614571565b602090810291909101015261171b60018a6144a4565b985086818151811061172f5761172f614571565b60200260200101518261174291906144fd565b91508061174e81614540565b9150506116d4565b5080866117646001866144fd565b8151811061177457611774614571565b602002602001018181525050879450505050509250925092565b60008060008060008060006117a589896001612ae5565b6040516311430cf160e31b815260048101879052939a509198509096509294509092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169150638a1867889060240160206040518083038186803b15801561181557600080fd5b505afa158015611829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184d9190613b15565b6040516311430cf160e31b8152600481018390529097507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638a1867889060240160206040518083038186803b1580156118b057600080fd5b505afa1580156118c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e89190613b15565b955050509295509295909350565b600080808080611906868261116e565b965091945092509050600061191b87866122d5565b90506119286020866144a4565b9450600061193688876122d5565b90506119436020876144a4565b955060608061088c8a89610636565b3361195b6110c8565b6001600160a01b0316146119815760405162461bcd60e51b81526004016105e390614311565b6001600160a01b0381166119e65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105e3565b6119ef81612371565b50565b60006119ff8260016144a4565b83511015611a455760405162461bcd60e51b8152602060048201526013602482015272746f55696e74385f6f75744f66426f756e647360681b60448201526064016105e3565b50016001015190565b6000611a5b8260026144a4565b83511015611aa25760405162461bcd60e51b8152602060048201526014602482015273746f55696e7431365f6f75744f66426f756e647360601b60448201526064016105e3565b50016002015190565b60008060ff8516611ad457611ac08484612c52565b9150611acd8360146144a4565b9050611cdc565b8460ff1660011415611b9b576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016638a186788611b198686612cb7565b6040516001600160e01b031960e084901b16815263ffffffff91909116600482015260240160206040518083038186803b158015611b5657600080fd5b505afa158015611b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8e9190613b15565b9150611acd8360046144a4565b8460ff1660021415611c60576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016638a186788611be08686612d14565b6040516001600160e01b031960e084901b16815262ffffff909116600482015260240160206040518083038186803b158015611c1b57600080fd5b505afa158015611c2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c539190613b15565b9150611acd8360036144a4565b8460ff1660031415611c7757506000905081611cdc565b60405162461bcd60e51b815260206004820152603460248201527f57617264656e44617461446573657269616c697a653a5f6c6f6f6b75704164646044820152733932b9b9903130b21034b739ba393ab1ba34b7b760611b60648201526084016105e3565b935093915050565b600080808080611cf488886119f2565b9050611d016001886144a4565b9650603f600282901c1690600316611d1a818a8a612d71565b98509550603f600283901c1691600316611d35818b8b612d71565b9950955087611d5957600183811c607f169316611d53818c8c612b9d565b9a509550505b88935050505093509350935093565b600080806000805160206145d38339815191526001600160a01b03851614611d905783611db2565b7f00000000000000000000000000000000000000000000000000000000000000005b905060006000805160206145d38339815191526001600160a01b0388161415611e9357853414611df45760405162461bcd60e51b81526004016105e3906141dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b158015611e4f57600080fd5b505af1158015611e63573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000009250309050611e99565b50859150335b6040516370a0823160e01b81526000906001600160a01b038516906370a0823190611ec89085906004016140c1565b60206040518083038186803b158015611ee057600080fd5b505afa158015611ef4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f189190613cd8565b90506000836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611f4891906140c1565b60206040518083038186803b158015611f6057600080fd5b505afa158015611f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f989190613cd8565b9050611fa88b8b878b8888612e84565b9550611fb488836144fd565b6040516370a0823160e01b81526001600160a01b038716906370a0823190611fe09087906004016140c1565b60206040518083038186803b158015611ff857600080fd5b505afa15801561200c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120309190613cd8565b1461204d5760405162461bcd60e51b81526004016105e390614226565b61205786826144a4565b6040516370a0823160e01b81526001600160a01b038616906370a08231906120839030906004016140c1565b60206040518083038186803b15801561209b57600080fd5b505afa1580156120af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d39190613cd8565b146120f05760405162461bcd60e51b81526004016105e390614346565b6000805160206145d38339815191526001600160a01b038816141561218a57604051632e1a7d4d60e01b8152600481018790527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561217157600080fd5b505af1158015612185573d6000803e3d6000fd5b505050505b505050505095945050505050565b6004805460405163c62dc9ef60e01b81526001600160a01b038a81169382019390935288831660248201526044810188905260648101879052858316608482015284831660a482015283151560c48201526000928392839291169063c62dc9ef9060e4016040805180830381600087803b15801561221557600080fd5b505af1158015612229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224d919061400c565b9092509050811561226357612263898383613057565b6108a282886144fd565b6040516001600160a01b0383166024820152604481018290526122d090849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613185565b505050565b60006122e28260206144a4565b8351101561232a5760405162461bcd60e51b8152602060048201526015602482015274746f55696e743235365f6f75744f66426f756e647360581b60448201526064016105e3565b50016020015190565b6040516001600160a01b038085166024830152831660448201526064810182905261236b9085906323b872dd60e01b90608401612299565b50505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008351600186516123d391906144fd565b146124385760405162461bcd60e51b815260206004820152602f60248201527f57617264656e537761703a20726f7574657320616e6420746f6b656e73206c6560448201526e1b99dd1a081b5a5cdb585d18da1959608a1b60648201526084016105e3565b6000806000805160206145d38339815191526001600160a01b038a161461245f5788612481565b7f00000000000000000000000000000000000000000000000000000000000000005b905060006000805160206145d38339815191526001600160a01b038d161415612562578a34146124c35760405162461bcd60e51b81526004016105e3906141dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08c6040518263ffffffff1660e01b81526004016000604051808303818588803b15801561251e57600080fd5b505af1158015612532573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000009250309050612568565b508a9150335b6040516370a0823160e01b81526000906001600160a01b038516906370a08231906125979085906004016140c1565b60206040518083038186803b1580156125af57600080fd5b505afa1580156125c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e79190613cd8565b90506000836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161261791906140c1565b60206040518083038186803b15801561262f57600080fd5b505afa158015612643573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126679190613cd8565b9050612677858e868d8d88613257565b95506126838d836144fd565b6040516370a0823160e01b81526001600160a01b038716906370a08231906126af9087906004016140c1565b60206040518083038186803b1580156126c757600080fd5b505afa1580156126db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ff9190613cd8565b1461271c5760405162461bcd60e51b81526004016105e390614226565b61272686826144a4565b6040516370a0823160e01b81526001600160a01b038616906370a08231906127529030906004016140c1565b60206040518083038186803b15801561276a57600080fd5b505afa15801561277e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a29190613cd8565b146127bf5760405162461bcd60e51b81526004016105e390614346565b5050505050866001600160a01b03166000805160206145d38339815191526001600160a01b0316141561286757604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561284e57600080fd5b505af1158015612862573d6000803e3d6000fd5b505050505b61287789888a8433886000612198565b9050858110156128995760405162461bcd60e51b81526004016105e3906142c7565b6000805160206145d38339815191526001600160a01b0388161415612931576000836001600160a01b03168260405160006040518083038185875af1925050503d8060008114612905576040519150601f19603f3d011682016040523d82523d6000602084013e61290a565b606091505b505090508061292b5760405162461bcd60e51b81526004016105e390614276565b50612945565b6129456001600160a01b038816848361226d565b81806129d257600354604051634b54ddad60e11b81526001600160a01b03909116906396a9bb5a9061297d9089908990600401614106565b602060405180830381600087803b15801561299757600080fd5b505af11580156129ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129cf9190613cd8565b90505b6003546040516329c2393b60e01b81526001600160a01b03909116906329c2393b90612a0a908d908c908e90889088906004016140d5565b602060405180830381600087803b158015612a2457600080fd5b505af1158015612a38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a5c9190613ca4565b50336001600160a01b0316886001600160a01b03168b6001600160a01b03166000805160206145b38339815191528c868989600014156000604051612aa59594939291906143d2565b60405180910390a45098975050505050505050565b606081604051602001612acf91815260200190565b6040516020818303038152906040529050919050565b60008080808080612af68989612d14565b62ffffff169550612b086003896144a4565b9750612b148989612d14565b62ffffff169450612b266003896144a4565b9750612b3289896134d1565b6001600160601b03169350612b48600c896144a4565b9750612b5489896134d1565b6001600160601b03169250612b6a600c896144a4565b975086612b8f57612b7b8989611a4e565b61ffff169150612b8c6002896144a4565b97505b509397929650909490935090565b60008060ff8516612bc357612bb28484611a4e565b61ffff169150611acd8360026144a4565b8460ff1660011415612beb57612bd98484612d14565b62ffffff169150611acd8360036144a4565b60405162461bcd60e51b815260206004820152603660248201527f57617264656e44617461446573657269616c697a653a5f6465636f64654c6561604482015275393732b224b2103130b21034b739ba393ab1ba34b7b760511b60648201526084016105e3565b6000612c5f8260146144a4565b83511015612ca75760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016105e3565b500160200151600160601b900490565b6000612cc48260046144a4565b83511015612d0b5760405162461bcd60e51b8152602060048201526014602482015273746f55696e7433325f6f75744f66426f756e647360601b60448201526064016105e3565b50016004015190565b6000612d218260036144a4565b83511015612d685760405162461bcd60e51b8152602060048201526014602482015273746f55696e7432345f6f75744f66426f756e647360601b60448201526064016105e3565b50016003015190565b60008060ff8516612d9c57612d86848461352e565b6001600160401b03169150611acd8360086144a4565b8460ff1660011415612dc857612db2848461358b565b6001600160501b03169150611acd83600a6144a4565b8460ff1660021415612df457612dde84846134d1565b6001600160601b03169150611acd83600c6144a4565b8460ff1660031415612e2057612e0a84846135e8565b6001600160701b03169150611acd83600e6144a4565b60405162461bcd60e51b815260206004820152603360248201527f57617264656e44617461446573657269616c697a653a5f6465636f6465416d6f6044820152723ab73a103130b21034b739ba393ab1ba34b7b760691b60648201526084016105e3565b600083815b885181101561304b57600060018a51612ea291906144fd565b821415612eb0575081612ef0565b6064898381518110612ec457612ec4614571565b602002602001015188612ed791906144de565b612ee191906144bc565b9050612eed81846144fd565b92505b6003548a516000916001600160a01b03169063972f4143908d9086908110612f1a57612f1a614571565b60200260200101516040518263ffffffff1660e01b8152600401612f4091815260200190565b60206040518083038186803b158015612f5857600080fd5b505afa158015612f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f909190613cd8565b60035460405163345c341560e21b81526004810183905291925060009182916001600160a01b03169063d170d0549060240160006040518083038186803b158015612fda57600080fd5b505afa158015612fee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130169190810190613b32565b915091506130288b858b85858d613257565b61303290886144a4565b965050505050808061304390614540565b915050612e89565b50509695505050505050565b6000805160206145d38339815191526001600160a01b038416141561311f576000816001600160a01b03168360405160006040518083038185875af1925050503d80600081146130c3576040519150601f19603f3d011682016040523d82523d6000602084013e6130c8565b606091505b50509050806131195760405162461bcd60e51b815260206004820152601d60248201527f5472616e7366657220666565206f66206574686572206661696c65642e00000060448201526064016105e3565b50613133565b6131336001600160a01b038416828461226d565b806001600160a01b0316836001600160a01b03167f63641fd2aeafea4143cc44c28ca8af48dde6326ee1be502b0222b4f92dfae2838460405161317891815260200190565b60405180910390a3505050565b60006131da826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166136469092919063ffffffff16565b8051909150156122d057808060200190518101906131f89190613ca4565b6122d05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105e3565b825185906000908190815b818110156134c3578015613299578661327c6001836144fd565b8151811061328c5761328c614571565b602002602001015161329b565b8a5b93506132a86001836144fd565b81146132cd578681815181106132c0576132c0614571565b60200260200101516132cf565b885b925060008882815181106132e5576132e5614571565b60200260200101519050600082600014613300576000613302565b875b905060006133116001866144fd565b84141561331f57503061349d565b6002546000906001600160a01b031663e254a4f38d61333f8860016144a4565b8151811061334f5761334f614571565b60200260200101516040518263ffffffff1660e01b815260040161337591815260200190565b60006040518083038186803b15801561338d57600080fd5b505afa1580156133a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133c99190810190613f16565b60400151905060006133dc6001886144fd565b6133e78760016144a4565b14613415578b6133f88760016144a4565b8151811061340857613408614571565b6020026020010151613417565b8d5b604051632717650960e01b81529091506001600160a01b03831690632717650990613448908b90859060040161418f565b60206040518083038186803b15801561346057600080fd5b505afa158015613474573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134989190613b15565b925050505b6134ab83888a89868661365f565b975050505080806134bb90614540565b915050613262565b505050509695505050505050565b60006134de82600c6144a4565b835110156135255760405162461bcd60e51b8152602060048201526014602482015273746f55696e7439365f6f75744f66426f756e647360601b60448201526064016105e3565b5001600c015190565b600061353b8260086144a4565b835110156135825760405162461bcd60e51b8152602060048201526014602482015273746f55696e7436345f6f75744f66426f756e647360601b60448201526064016105e3565b50016008015190565b600061359882600a6144a4565b835110156135df5760405162461bcd60e51b8152602060048201526014602482015273746f55696e7438305f6f75744f66426f756e647360601b60448201526064016105e3565b5001600a015190565b60006135f582600e6144a4565b8351101561363d5760405162461bcd60e51b8152602060048201526015602482015274746f55696e743131325f6f75744f66426f756e647360581b60448201526064016105e3565b5001600e015190565b60606136558484600085613850565b90505b9392505050565b60025460405163e254a4f360e01b81526004810188905260009182916001600160a01b039091169063e254a4f39060240160006040518083038186803b1580156136a857600080fd5b505afa1580156136bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526136e49190810190613f16565b6040015190506000816001600160a01b0316632717650989886040518363ffffffff1660e01b815260040161371a92919061418f565b60206040518083038186803b15801561373257600080fd5b505afa158015613746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061376a9190613b15565b90506001600160a01b038516301415613796576137916001600160a01b038916828961226d565b6137ba565b6001600160a01b038516156137ba576137ba6001600160a01b03891686838a612333565b60405163d76d0c5b60e01b81526001600160a01b03898116600483015287811660248301526044820189905285811660648301526000919084169063d76d0c5b90608401602060405180830381600087803b15801561381857600080fd5b505af115801561382c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a29190613cd8565b6060824710156138b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105e3565b843b6138ff5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105e3565b600080866001600160a01b0316858760405161391b91906140a5565b60006040518083038185875af1925050503d8060008114613958576040519150601f19603f3d011682016040523d82523d6000602084013e61395d565b606091505b5091509150610b1982828660608315613977575081613658565b8251156139875782518084602001fd5b8160405162461bcd60e51b81526004016105e391906141a9565b80356139ac8161459d565b919050565b600082601f8301126139c257600080fd5b815160206139d76139d28361445a565b61442a565b80838252828201915082860187848660051b89010111156139f757600080fd5b60005b85811015613a1f578151613a0d8161459d565b845292840192908401906001016139fa565b5090979650505050505050565b600082601f830112613a3d57600080fd5b81356020613a4d6139d28361445a565b80838252828201915082860187848660051b8901011115613a6d57600080fd5b60005b85811015613a1f57813584529284019290840190600101613a70565b805180151581146139ac57600080fd5b600082601f830112613aad57600080fd5b8135613abb6139d28261447d565b818152846020838601011115613ad057600080fd5b816020850160208301376000918101602001919091529392505050565b80516139ac8161459d565b600060208284031215613b0a57600080fd5b81356136588161459d565b600060208284031215613b2757600080fd5b81516136588161459d565b60008060408385031215613b4557600080fd5b82516001600160401b0380821115613b5c57600080fd5b818501915085601f830112613b7057600080fd5b81516020613b806139d28361445a565b8083825282820191508286018a848660051b8901011115613ba057600080fd5b600096505b84871015613bc3578051835260019690960195918301918301613ba5565b5091880151919650909350505080821115613bdd57600080fd5b50613bea858286016139b1565b9150509250929050565b600080600080600080600060e0888a031215613c0f57600080fd5b87356001600160401b0380821115613c2657600080fd5b613c328b838c01613a2c565b985060208a0135915080821115613c4857600080fd5b50613c558a828b01613a2c565b9650506040880135613c668161459d565b9450606088013593506080880135613c7d8161459d565b925060a0880135915060c0880135613c948161459d565b8091505092959891949750929550565b600060208284031215613cb657600080fd5b61365882613a8c565b600060208284031215613cd157600080fd5b5035919050565b600060208284031215613cea57600080fd5b5051919050565b600060208284031215613d0357600080fd5b81356001600160401b03811115613d1957600080fd5b613d2584828501613a9c565b949350505050565b60008060408385031215613d4057600080fd5b82356001600160401b03811115613d5657600080fd5b613d6285828601613a9c565b95602094909401359450505050565b60008060408385031215613d8457600080fd5b8235613d8f8161459d565b946020939093013593505050565b600080600080600080600060e0888a031215613db857600080fd5b8735613dc38161459d565b965060208881013596506040890135613ddb8161459d565b95506060890135945060808901356001600160401b0380821115613dfe57600080fd5b613e0a8c838d01613a2c565b955060a08b0135915080821115613e2057600080fd5b508901601f81018b13613e3257600080fd5b8035613e406139d28261445a565b8082825284820191508484018e868560051b8701011115613e6057600080fd5b600094505b83851015613e8c578035613e788161459d565b835260019490940193918501918501613e65565b508096505050505050613ea160c089016139a1565b905092959891949750929550565b60008060008060008060c08789031215613ec857600080fd5b8635613ed38161459d565b9550602087013594506040870135613eea8161459d565b9350606087013592506080870135915060a0870135613f088161459d565b809150509295509295509295565b60006020808385031215613f2957600080fd5b82516001600160401b0380821115613f4057600080fd5b9084019060608287031215613f5457600080fd5b613f5c614402565b825182811115613f6b57600080fd5b83019150601f82018713613f7e57600080fd5b8151613f8c6139d28261447d565b8181528886838601011115613fa057600080fd5b613faf82878301888701614514565b825250613fbd838501613a8c565b84820152613fcd60408401613aed565b60408201529695505050505050565b60008060408385031215613fef57600080fd5b8235915060208301356140018161459d565b809150509250929050565b6000806040838503121561401f57600080fd5b8251915060208301516140018161459d565b600081518084526020808501945080840160005b8381101561406a5781516001600160a01b031687529582019590820190600101614045565b509495945050505050565b600081518084526020808501945080840160005b8381101561406a57815187529582019590820190600101614089565b600082516140b7818460208701614514565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03958616815293909416602084015260408301919091526060820152608081019190915260a00190565b6040815260006141196040830185614075565b828103602084015261412b8185614031565b95945050505050565b6060815260006141476060830186614075565b82810360208401526141598186614031565b915050826040830152949350505050565b60608152600061417d6060830186614075565b82810360208401526141598186614075565b6001600160a01b0392831681529116602082015260400190565b60208152600082518060208401526141c8816040850160208701614514565b601f01601f19169190910160400192915050565b6020808252602a908201527f57617264656e537761703a20457468657220736f7572636520616d6f756e74206040820152691b5a5cdb585d18da195960b21b606082015260800190565b60208082526030908201527f57617264656e537761703a20736f7572636520616d6f756e74206d69736d617460408201526f6368656420616674657220747261646560801b606082015260800190565b60208082526031908201527f57617264656e537761703a205472616e73666572206574686572206261636b206040820152703a379031b0b63632b9103330b4b632b21760791b606082015260800190565b6020808252602a908201527f57617264656e537761703a2064657374696e6174696f6e20616d6f756e74206960408201526939903a37b7903637bb9760b11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526035908201527f57617264656e537761703a2064657374696e6174696f6e20616d6f756e74206d60408201527469736d61746368656420616674657220747261646560581b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b94855260208501939093526001600160a01b03919091166040840152151560608301521515608082015260a00190565b604051606081016001600160401b038111828210171561442457614424614587565b60405290565b604051601f8201601f191681016001600160401b038111828210171561445257614452614587565b604052919050565b60006001600160401b0382111561447357614473614587565b5060051b60200190565b60006001600160401b0382111561449657614496614587565b50601f01601f191660200190565b600082198211156144b7576144b761455b565b500190565b6000826144d957634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156144f8576144f861455b565b500290565b60008282101561450f5761450f61455b565b500390565b60005b8381101561452f578181015183820152602001614517565b8381111561236b5750506000910152565b60006000198214156145545761455461455b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146119ef57600080fdfe7acb84937815db1a71622c24a8f03661982c6ac39f087563b5033ab1c9d2cbbd000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeea26469706673582212203fe43e9d5767501c95f9d4f08d2775fa221c770fb1d3221f7d124546bb927e6464736f6c634300080700330000000000000000000000001a5f88fb85bd2b5eb1b5dc738ae02a5f0a69729f000000000000000000000000ac8b2026587e2e9f83f066cd302b1b71dc41f6e300000000000000000000000071ac17934b60a4610dc58b715b61e45dcbde405400000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab10000000000000000000000000000000000000000000000000000000000000066
Deployed Bytecode
0x6080604052600436106101825760003560e01c806310b8e70f1461018e57806312d3a396146101b0578063199d34cf146101e8578063278203ba1461022357806327d2f16c1461027857806332cc1c5d146102a557806335689011146102c65780633ca58a01146102d95780634912dd14146102ec5780634cf6455b1461030c5780634f7919dd1461031f57806350c57d1d1461033f5780635a5e959c14610352578063613f8bbe146103655780636293263914610378578063629e14251461038b57806366f7c956146103ab5780636d16ecee146103cb578063715018a6146103eb57806378fc6db0146104005780637ab3e6451461041357806381d22e9a146104535780638da5cb5b146104665780638f64d73a1461047b57806397f8b0961461049b578063bc0488fa146104bb578063c292fc1b146104db578063c8a7c7e51461050c578063dca489e01461051f578063e77040f414610532578063eaeff54914610561578063f13a9ad814610581578063f2fde38b1461059457600080fd5b3661018957005b600080fd5b34801561019a57600080fd5b506101ae6101a9366004613af8565b6105b4565b005b3480156101bc57600080fd5b506101d06101cb366004613d2d565b610636565b6040516101df93929190614134565b60405180910390f35b3480156101f457600080fd5b50610208610203366004613d2d565b6107c1565b604080519384526020840192909252908201526060016101df565b34801561022f57600080fd5b5061024361023e366004613d2d565b6107e1565b6040516101df94939291906001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b34801561028457600080fd5b50600454610298906001600160a01b031681565b6040516101df91906140c1565b6102b86102b3366004613cf1565b610852565b6040519081526020016101df565b6102b86102d4366004613bf4565b6108b0565b6102b86102e7366004613cbf565b610aef565b3480156102f857600080fd5b506101ae610307366004613d71565b610b24565b6102b861031a366004613cf1565b610b6b565b34801561032b57600080fd5b50600254610298906001600160a01b031681565b6102b861034d366004613cf1565b610bf0565b6102b8610360366004613cf1565b610c30565b6102b8610373366004613cf1565b610c80565b6102b8610386366004613cf1565b610cc0565b34801561039757600080fd5b506102b86103a6366004613fdc565b610d1c565b3480156103b757600080fd5b506101ae6103c6366004613af8565b610ef0565b3480156103d757600080fd5b506101ae6103e6366004613af8565b610f69565b3480156103f757600080fd5b506101ae610fe2565b6102b861040e366004613d9d565b61101d565b34801561041f57600080fd5b5061043361042e366004613d2d565b611068565b6040805194855260208501939093529183015260608201526080016101df565b6102b8610461366004613cf1565b61108a565b34801561047257600080fd5b506102986110c8565b34801561048757600080fd5b506101ae610496366004613cbf565b6110d7565b3480156104a757600080fd5b50600354610298906001600160a01b031681565b3480156104c757600080fd5b506102436104d6366004613d2d565b61116e565b3480156104e757600080fd5b506104fb6104f6366004613cbf565b6111a3565b6040516101df9594939291906140d5565b6102b861051a366004613eaf565b611315565b6102b861052d366004613af8565b611468565b34801561053e57600080fd5b5061055261054d366004613d2d565b6115c6565b6040516101df9392919061416a565b34801561056d57600080fd5b506104fb61057c366004613d2d565b61178e565b6102b861058f366004613cf1565b6118f6565b3480156105a057600080fd5b506101ae6105af366004613af8565b611952565b336105bd6110c8565b6001600160a01b0316146105ec5760405162461bcd60e51b81526004016105e390614311565b60405180910390fd5b600480546001600160a01b0319166001600160a01b0383169081179091556040517ff3809f73f1bea6bcad288beb0538a25e1b98b4388cc422d087050ff52f7cbf8790600090a250565b60608060008061064686866119f2565b90506106536001866144a4565b9450600090603f81169060061c600316816001600160401b0381111561067b5761067b614587565b6040519080825280602002602001820160405280156106a4578160200160208202803683370190505b5095506106b26001836144fd565b6001600160401b038111156106c9576106c9614587565b6040519080825280602002602001820160405280156106f2578160200160208202803683370190505b50945060005b8281101561074a5761070a8989611a4e565b61ffff1687828151811061072057610720614571565b60209081029190910101526107366002896144a4565b97508061074281614540565b9150506106f8565b5060005b6107596001846144fd565b8110156107b357600061076d838b8b611aab565b809a5081925050508087838151811061078857610788614571565b6001600160a01b039092166020928302919091019091015250806107ab81614540565b91505061074e565b508693505050509250925092565b60008060006107d285856001611ce4565b92989197509195509350505050565b6000808080806107f187876119f2565b90506107fe6001876144a4565b95506003600682901c81169181811691600282901c81169160041c16610825838b8b611aab565b99509750610834828b8b611aab565b99509650610843818b8b611aab565b989b979a509850505050505050565b600080808080610862868261116e565b96509194509250905060008061087888876107c1565b9750909250905060608061088c8a89610636565b995090925090506108a28785888686868b61101d565b9a9950505050505050505050565b6000600260015414156108d55760405162461bcd60e51b81526004016105e39061439b565b600260015587516109385760405162461bcd60e51b815260206004820152602760248201527f57617264656e537761703a206c6561726e65644964732063616e206e6f7420626044820152666520656d70747960c81b60648201526084016105e3565b86518851146109a75760405162461bcd60e51b815260206004820152603560248201527f57617264656e537761703a206c6561726e656449647320616e6420766f6c756d6044820152741b9cc81b195b99dd1a1cc81b5a5cdb585d18da1959605a1b60648201526084016105e3565b6109b48888888888611d68565b90506109c68685878433876001612198565b9050828110156109e85760405162461bcd60e51b81526004016105e3906142c7565b6000805160206145d38339815191526001600160a01b0385161415610a80576000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610a54576040519150601f19603f3d011682016040523d82523d6000602084013e610a59565b606091505b5050905080610a7a5760405162461bcd60e51b81526004016105e390614276565b50610a94565b610a946001600160a01b038516838361226d565b336001600160a01b0316846001600160a01b0316876001600160a01b03166000805160206145b3833981519152888587600180604051610ad89594939291906143d2565b60405180910390a460018055979650505050505050565b600080600080600080610b01876111a3565b94509450945094509450610b19858486858533611315565b979650505050505050565b33610b2d6110c8565b6001600160a01b031614610b535760405162461bcd60e51b81526004016105e390614311565b610b676001600160a01b038316338361226d565b5050565b600080808080610b7b868261116e565b9650919450925090506000610b9087866122d5565b9050610b9d6020866144a4565b94506000610bab88876122d5565b9050610bb86020876144a4565b95506000610bc689886122d5565b9050610bd36020886144a4565b9650610be3868487858589611315565b9998505050505050505050565b60008080808080610c01878261178e565b985092965090945092509050606080610c1a89886115c6565b98509092509050610be3828288878988336108b0565b600080808080610c40868261116e565b965091945092509050600080610c5688876107c1565b97509092509050606080610c6a8a896115c6565b995090925090506108a2828289878a888b6108b0565b60008080808080610c91878261178e565b985092965090945092509050606080610caa8988610636565b98509092509050610be38685878686863361101d565b600080808080610cd0868261116e565b9650919450925090506000610ce587866122d5565b9050610cf26020866144a4565b94506000610d0088876122d5565b9050610d0d6020876144a4565b9550606080610c6a8a896115c6565b600060026001541415610d415760405162461bcd60e51b81526004016105e39061439b565b6002600155610d7b6001600160a01b037f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab116333086612333565b604051632e1a7d4d60e01b8152600481018490527f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015610ddd57600080fd5b505af1158015610df1573d6000803e3d6000fd5b505050506000826001600160a01b03168460405160006040518083038185875af1925050503d8060008114610e42576040519150601f19603f3d011682016040523d82523d6000602084013e610e47565b606091505b5050905080610e685760405162461bcd60e51b81526004016105e390614276565b839150336001600160a01b03166000805160206145d38339815191526001600160a01b03167f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b03166000805160206145b3833981519152878688600080604051610edd9594939291906143d2565b60405180910390a4506001805592915050565b33610ef96110c8565b6001600160a01b031614610f1f5760405162461bcd60e51b81526004016105e390614311565b600380546001600160a01b0319166001600160a01b0383169081179091556040517fb9471cba7e6c6e177386e0b3e0a38c3414efdf1a9a5f199755b2dc979ad4ecd890600090a250565b33610f726110c8565b6001600160a01b031614610f985760405162461bcd60e51b81526004016105e390614311565b600280546001600160a01b0319166001600160a01b0383169081179091556040517fa524ebbfbe21120240da574f40225bd07c7ac918927b018a847e29319cb7e14790600090a250565b33610feb6110c8565b6001600160a01b0316146110115760405162461bcd60e51b81526004016105e390614311565b61101b6000612371565b565b6000600260015414156110425760405162461bcd60e51b81526004016105e39061439b565b60026001556110588888888888888860006123c1565b6001805598975050505050505050565b60008060008061107a86866000611ce4565b9299919850965090945092505050565b60008080808061109a868261116e565b965091945092509050600080806110b18988611068565b995091945092509050610be3868487858589611315565b6000546001600160a01b031690565b336110e06110c8565b6001600160a01b0316146111065760405162461bcd60e51b81526004016105e390614311565b604051600090339083908381818185875af1925050503d8060008114611148576040519150601f19603f3d011682016040523d82523d6000602084013e61114d565b606091505b5050905080610b675760405162461bcd60e51b81526004016105e390614276565b60008060008061117e86866107e1565b929650909450925090506001600160a01b03821661119a573391505b92959194509250565b6000806000806000806111b587612aba565b90506000806111c683600080612ae5565b506040516311430cf160e31b815260048101869052929a50909850965091935091507f00000000000000000000000000000000000000000000000000000000000000666001600160a01b031690638a1867889060240160206040518083038186803b15801561123457600080fd5b505afa158015611248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126c9190613b15565b6040516311430cf160e31b8152600481018390529098507f00000000000000000000000000000000000000000000000000000000000000666001600160a01b031690638a1867889060240160206040518083038186803b1580156112cf57600080fd5b505afa1580156112e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113079190613b15565b965050505091939590929450565b60006002600154141561133a5760405162461bcd60e51b81526004016105e39061439b565b600260015560035460405163972f414360e01b8152600481018590526000916001600160a01b03169063972f41439060240160206040518083038186803b15801561138457600080fd5b505afa158015611398573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113bc9190613cd8565b60035460405163345c341560e21b81526004810183905291925060009182916001600160a01b03169063d170d0549060240160006040518083038186803b15801561140657600080fd5b505afa15801561141a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114429190810190613b32565b915091506114568a8a8a8a86868b8d6123c1565b600180559a9950505050505050505050565b60006002600154141561148d5760405162461bcd60e51b81526004016105e39061439b565b60026001819055507f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156114f057600080fd5b505af1158015611504573d6000803e3d6000fd5b506115409350506001600160a01b037f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab11691508490503461226d565b349050336001600160a01b03167f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b03166000805160206145d38339815191526001600160a01b03166000805160206145b38339815191523485876000806040516115b59594939291906143d2565b60405180910390a460018055919050565b6060806000806115d686866119f2565b90506115e36001866144a4565b94506001600782901c811691603f81169160069190911c16816001600160401b0381111561161357611613614587565b60405190808252806020026020018201604052801561163c578160200160208202803683370190505b50955060005b8281101561168a57611655828a8a612b9d565b88838151811061166757611667614571565b60200260200101819a50828152505050808061168290614540565b915050611642565b50816001600160401b038111156116a3576116a3614587565b6040519080825280602002602001820160405280156116cc578160200160208202803683370190505b509450606460005b6116df6001856144fd565b811015611756576116f08a8a6119f2565b60ff1687828151811061170557611705614571565b602090810291909101015261171b60018a6144a4565b985086818151811061172f5761172f614571565b60200260200101518261174291906144fd565b91508061174e81614540565b9150506116d4565b5080866117646001866144fd565b8151811061177457611774614571565b602002602001018181525050879450505050509250925092565b60008060008060008060006117a589896001612ae5565b6040516311430cf160e31b815260048101879052939a509198509096509294509092507f00000000000000000000000000000000000000000000000000000000000000666001600160a01b03169150638a1867889060240160206040518083038186803b15801561181557600080fd5b505afa158015611829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184d9190613b15565b6040516311430cf160e31b8152600481018390529097507f00000000000000000000000000000000000000000000000000000000000000666001600160a01b031690638a1867889060240160206040518083038186803b1580156118b057600080fd5b505afa1580156118c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e89190613b15565b955050509295509295909350565b600080808080611906868261116e565b965091945092509050600061191b87866122d5565b90506119286020866144a4565b9450600061193688876122d5565b90506119436020876144a4565b955060608061088c8a89610636565b3361195b6110c8565b6001600160a01b0316146119815760405162461bcd60e51b81526004016105e390614311565b6001600160a01b0381166119e65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105e3565b6119ef81612371565b50565b60006119ff8260016144a4565b83511015611a455760405162461bcd60e51b8152602060048201526013602482015272746f55696e74385f6f75744f66426f756e647360681b60448201526064016105e3565b50016001015190565b6000611a5b8260026144a4565b83511015611aa25760405162461bcd60e51b8152602060048201526014602482015273746f55696e7431365f6f75744f66426f756e647360601b60448201526064016105e3565b50016002015190565b60008060ff8516611ad457611ac08484612c52565b9150611acd8360146144a4565b9050611cdc565b8460ff1660011415611b9b576001600160a01b037f000000000000000000000000000000000000000000000000000000000000006616638a186788611b198686612cb7565b6040516001600160e01b031960e084901b16815263ffffffff91909116600482015260240160206040518083038186803b158015611b5657600080fd5b505afa158015611b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8e9190613b15565b9150611acd8360046144a4565b8460ff1660021415611c60576001600160a01b037f000000000000000000000000000000000000000000000000000000000000006616638a186788611be08686612d14565b6040516001600160e01b031960e084901b16815262ffffff909116600482015260240160206040518083038186803b158015611c1b57600080fd5b505afa158015611c2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c539190613b15565b9150611acd8360036144a4565b8460ff1660031415611c7757506000905081611cdc565b60405162461bcd60e51b815260206004820152603460248201527f57617264656e44617461446573657269616c697a653a5f6c6f6f6b75704164646044820152733932b9b9903130b21034b739ba393ab1ba34b7b760611b60648201526084016105e3565b935093915050565b600080808080611cf488886119f2565b9050611d016001886144a4565b9650603f600282901c1690600316611d1a818a8a612d71565b98509550603f600283901c1691600316611d35818b8b612d71565b9950955087611d5957600183811c607f169316611d53818c8c612b9d565b9a509550505b88935050505093509350935093565b600080806000805160206145d38339815191526001600160a01b03851614611d905783611db2565b7f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab15b905060006000805160206145d38339815191526001600160a01b0388161415611e9357853414611df45760405162461bcd60e51b81526004016105e3906141dc565b7f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b031663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b158015611e4f57600080fd5b505af1158015611e63573d6000803e3d6000fd5b50505050507f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab19250309050611e99565b50859150335b6040516370a0823160e01b81526000906001600160a01b038516906370a0823190611ec89085906004016140c1565b60206040518083038186803b158015611ee057600080fd5b505afa158015611ef4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f189190613cd8565b90506000836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611f4891906140c1565b60206040518083038186803b158015611f6057600080fd5b505afa158015611f74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f989190613cd8565b9050611fa88b8b878b8888612e84565b9550611fb488836144fd565b6040516370a0823160e01b81526001600160a01b038716906370a0823190611fe09087906004016140c1565b60206040518083038186803b158015611ff857600080fd5b505afa15801561200c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120309190613cd8565b1461204d5760405162461bcd60e51b81526004016105e390614226565b61205786826144a4565b6040516370a0823160e01b81526001600160a01b038616906370a08231906120839030906004016140c1565b60206040518083038186803b15801561209b57600080fd5b505afa1580156120af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d39190613cd8565b146120f05760405162461bcd60e51b81526004016105e390614346565b6000805160206145d38339815191526001600160a01b038816141561218a57604051632e1a7d4d60e01b8152600481018790527f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561217157600080fd5b505af1158015612185573d6000803e3d6000fd5b505050505b505050505095945050505050565b6004805460405163c62dc9ef60e01b81526001600160a01b038a81169382019390935288831660248201526044810188905260648101879052858316608482015284831660a482015283151560c48201526000928392839291169063c62dc9ef9060e4016040805180830381600087803b15801561221557600080fd5b505af1158015612229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224d919061400c565b9092509050811561226357612263898383613057565b6108a282886144fd565b6040516001600160a01b0383166024820152604481018290526122d090849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613185565b505050565b60006122e28260206144a4565b8351101561232a5760405162461bcd60e51b8152602060048201526015602482015274746f55696e743235365f6f75744f66426f756e647360581b60448201526064016105e3565b50016020015190565b6040516001600160a01b038085166024830152831660448201526064810182905261236b9085906323b872dd60e01b90608401612299565b50505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008351600186516123d391906144fd565b146124385760405162461bcd60e51b815260206004820152602f60248201527f57617264656e537761703a20726f7574657320616e6420746f6b656e73206c6560448201526e1b99dd1a081b5a5cdb585d18da1959608a1b60648201526084016105e3565b6000806000805160206145d38339815191526001600160a01b038a161461245f5788612481565b7f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab15b905060006000805160206145d38339815191526001600160a01b038d161415612562578a34146124c35760405162461bcd60e51b81526004016105e3906141dc565b7f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b031663d0e30db08c6040518263ffffffff1660e01b81526004016000604051808303818588803b15801561251e57600080fd5b505af1158015612532573d6000803e3d6000fd5b50505050507f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab19250309050612568565b508a9150335b6040516370a0823160e01b81526000906001600160a01b038516906370a08231906125979085906004016140c1565b60206040518083038186803b1580156125af57600080fd5b505afa1580156125c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e79190613cd8565b90506000836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161261791906140c1565b60206040518083038186803b15801561262f57600080fd5b505afa158015612643573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126679190613cd8565b9050612677858e868d8d88613257565b95506126838d836144fd565b6040516370a0823160e01b81526001600160a01b038716906370a08231906126af9087906004016140c1565b60206040518083038186803b1580156126c757600080fd5b505afa1580156126db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ff9190613cd8565b1461271c5760405162461bcd60e51b81526004016105e390614226565b61272686826144a4565b6040516370a0823160e01b81526001600160a01b038616906370a08231906127529030906004016140c1565b60206040518083038186803b15801561276a57600080fd5b505afa15801561277e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a29190613cd8565b146127bf5760405162461bcd60e51b81526004016105e390614346565b5050505050866001600160a01b03166000805160206145d38339815191526001600160a01b0316141561286757604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab16001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561284e57600080fd5b505af1158015612862573d6000803e3d6000fd5b505050505b61287789888a8433886000612198565b9050858110156128995760405162461bcd60e51b81526004016105e3906142c7565b6000805160206145d38339815191526001600160a01b0388161415612931576000836001600160a01b03168260405160006040518083038185875af1925050503d8060008114612905576040519150601f19603f3d011682016040523d82523d6000602084013e61290a565b606091505b505090508061292b5760405162461bcd60e51b81526004016105e390614276565b50612945565b6129456001600160a01b038816848361226d565b81806129d257600354604051634b54ddad60e11b81526001600160a01b03909116906396a9bb5a9061297d9089908990600401614106565b602060405180830381600087803b15801561299757600080fd5b505af11580156129ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129cf9190613cd8565b90505b6003546040516329c2393b60e01b81526001600160a01b03909116906329c2393b90612a0a908d908c908e90889088906004016140d5565b602060405180830381600087803b158015612a2457600080fd5b505af1158015612a38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a5c9190613ca4565b50336001600160a01b0316886001600160a01b03168b6001600160a01b03166000805160206145b38339815191528c868989600014156000604051612aa59594939291906143d2565b60405180910390a45098975050505050505050565b606081604051602001612acf91815260200190565b6040516020818303038152906040529050919050565b60008080808080612af68989612d14565b62ffffff169550612b086003896144a4565b9750612b148989612d14565b62ffffff169450612b266003896144a4565b9750612b3289896134d1565b6001600160601b03169350612b48600c896144a4565b9750612b5489896134d1565b6001600160601b03169250612b6a600c896144a4565b975086612b8f57612b7b8989611a4e565b61ffff169150612b8c6002896144a4565b97505b509397929650909490935090565b60008060ff8516612bc357612bb28484611a4e565b61ffff169150611acd8360026144a4565b8460ff1660011415612beb57612bd98484612d14565b62ffffff169150611acd8360036144a4565b60405162461bcd60e51b815260206004820152603660248201527f57617264656e44617461446573657269616c697a653a5f6465636f64654c6561604482015275393732b224b2103130b21034b739ba393ab1ba34b7b760511b60648201526084016105e3565b6000612c5f8260146144a4565b83511015612ca75760405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b60448201526064016105e3565b500160200151600160601b900490565b6000612cc48260046144a4565b83511015612d0b5760405162461bcd60e51b8152602060048201526014602482015273746f55696e7433325f6f75744f66426f756e647360601b60448201526064016105e3565b50016004015190565b6000612d218260036144a4565b83511015612d685760405162461bcd60e51b8152602060048201526014602482015273746f55696e7432345f6f75744f66426f756e647360601b60448201526064016105e3565b50016003015190565b60008060ff8516612d9c57612d86848461352e565b6001600160401b03169150611acd8360086144a4565b8460ff1660011415612dc857612db2848461358b565b6001600160501b03169150611acd83600a6144a4565b8460ff1660021415612df457612dde84846134d1565b6001600160601b03169150611acd83600c6144a4565b8460ff1660031415612e2057612e0a84846135e8565b6001600160701b03169150611acd83600e6144a4565b60405162461bcd60e51b815260206004820152603360248201527f57617264656e44617461446573657269616c697a653a5f6465636f6465416d6f6044820152723ab73a103130b21034b739ba393ab1ba34b7b760691b60648201526084016105e3565b600083815b885181101561304b57600060018a51612ea291906144fd565b821415612eb0575081612ef0565b6064898381518110612ec457612ec4614571565b602002602001015188612ed791906144de565b612ee191906144bc565b9050612eed81846144fd565b92505b6003548a516000916001600160a01b03169063972f4143908d9086908110612f1a57612f1a614571565b60200260200101516040518263ffffffff1660e01b8152600401612f4091815260200190565b60206040518083038186803b158015612f5857600080fd5b505afa158015612f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f909190613cd8565b60035460405163345c341560e21b81526004810183905291925060009182916001600160a01b03169063d170d0549060240160006040518083038186803b158015612fda57600080fd5b505afa158015612fee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130169190810190613b32565b915091506130288b858b85858d613257565b61303290886144a4565b965050505050808061304390614540565b915050612e89565b50509695505050505050565b6000805160206145d38339815191526001600160a01b038416141561311f576000816001600160a01b03168360405160006040518083038185875af1925050503d80600081146130c3576040519150601f19603f3d011682016040523d82523d6000602084013e6130c8565b606091505b50509050806131195760405162461bcd60e51b815260206004820152601d60248201527f5472616e7366657220666565206f66206574686572206661696c65642e00000060448201526064016105e3565b50613133565b6131336001600160a01b038416828461226d565b806001600160a01b0316836001600160a01b03167f63641fd2aeafea4143cc44c28ca8af48dde6326ee1be502b0222b4f92dfae2838460405161317891815260200190565b60405180910390a3505050565b60006131da826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166136469092919063ffffffff16565b8051909150156122d057808060200190518101906131f89190613ca4565b6122d05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105e3565b825185906000908190815b818110156134c3578015613299578661327c6001836144fd565b8151811061328c5761328c614571565b602002602001015161329b565b8a5b93506132a86001836144fd565b81146132cd578681815181106132c0576132c0614571565b60200260200101516132cf565b885b925060008882815181106132e5576132e5614571565b60200260200101519050600082600014613300576000613302565b875b905060006133116001866144fd565b84141561331f57503061349d565b6002546000906001600160a01b031663e254a4f38d61333f8860016144a4565b8151811061334f5761334f614571565b60200260200101516040518263ffffffff1660e01b815260040161337591815260200190565b60006040518083038186803b15801561338d57600080fd5b505afa1580156133a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133c99190810190613f16565b60400151905060006133dc6001886144fd565b6133e78760016144a4565b14613415578b6133f88760016144a4565b8151811061340857613408614571565b6020026020010151613417565b8d5b604051632717650960e01b81529091506001600160a01b03831690632717650990613448908b90859060040161418f565b60206040518083038186803b15801561346057600080fd5b505afa158015613474573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134989190613b15565b925050505b6134ab83888a89868661365f565b975050505080806134bb90614540565b915050613262565b505050509695505050505050565b60006134de82600c6144a4565b835110156135255760405162461bcd60e51b8152602060048201526014602482015273746f55696e7439365f6f75744f66426f756e647360601b60448201526064016105e3565b5001600c015190565b600061353b8260086144a4565b835110156135825760405162461bcd60e51b8152602060048201526014602482015273746f55696e7436345f6f75744f66426f756e647360601b60448201526064016105e3565b50016008015190565b600061359882600a6144a4565b835110156135df5760405162461bcd60e51b8152602060048201526014602482015273746f55696e7438305f6f75744f66426f756e647360601b60448201526064016105e3565b5001600a015190565b60006135f582600e6144a4565b8351101561363d5760405162461bcd60e51b8152602060048201526015602482015274746f55696e743131325f6f75744f66426f756e647360581b60448201526064016105e3565b5001600e015190565b60606136558484600085613850565b90505b9392505050565b60025460405163e254a4f360e01b81526004810188905260009182916001600160a01b039091169063e254a4f39060240160006040518083038186803b1580156136a857600080fd5b505afa1580156136bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526136e49190810190613f16565b6040015190506000816001600160a01b0316632717650989886040518363ffffffff1660e01b815260040161371a92919061418f565b60206040518083038186803b15801561373257600080fd5b505afa158015613746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061376a9190613b15565b90506001600160a01b038516301415613796576137916001600160a01b038916828961226d565b6137ba565b6001600160a01b038516156137ba576137ba6001600160a01b03891686838a612333565b60405163d76d0c5b60e01b81526001600160a01b03898116600483015287811660248301526044820189905285811660648301526000919084169063d76d0c5b90608401602060405180830381600087803b15801561381857600080fd5b505af115801561382c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a29190613cd8565b6060824710156138b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105e3565b843b6138ff5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105e3565b600080866001600160a01b0316858760405161391b91906140a5565b60006040518083038185875af1925050503d8060008114613958576040519150601f19603f3d011682016040523d82523d6000602084013e61395d565b606091505b5091509150610b1982828660608315613977575081613658565b8251156139875782518084602001fd5b8160405162461bcd60e51b81526004016105e391906141a9565b80356139ac8161459d565b919050565b600082601f8301126139c257600080fd5b815160206139d76139d28361445a565b61442a565b80838252828201915082860187848660051b89010111156139f757600080fd5b60005b85811015613a1f578151613a0d8161459d565b845292840192908401906001016139fa565b5090979650505050505050565b600082601f830112613a3d57600080fd5b81356020613a4d6139d28361445a565b80838252828201915082860187848660051b8901011115613a6d57600080fd5b60005b85811015613a1f57813584529284019290840190600101613a70565b805180151581146139ac57600080fd5b600082601f830112613aad57600080fd5b8135613abb6139d28261447d565b818152846020838601011115613ad057600080fd5b816020850160208301376000918101602001919091529392505050565b80516139ac8161459d565b600060208284031215613b0a57600080fd5b81356136588161459d565b600060208284031215613b2757600080fd5b81516136588161459d565b60008060408385031215613b4557600080fd5b82516001600160401b0380821115613b5c57600080fd5b818501915085601f830112613b7057600080fd5b81516020613b806139d28361445a565b8083825282820191508286018a848660051b8901011115613ba057600080fd5b600096505b84871015613bc3578051835260019690960195918301918301613ba5565b5091880151919650909350505080821115613bdd57600080fd5b50613bea858286016139b1565b9150509250929050565b600080600080600080600060e0888a031215613c0f57600080fd5b87356001600160401b0380821115613c2657600080fd5b613c328b838c01613a2c565b985060208a0135915080821115613c4857600080fd5b50613c558a828b01613a2c565b9650506040880135613c668161459d565b9450606088013593506080880135613c7d8161459d565b925060a0880135915060c0880135613c948161459d565b8091505092959891949750929550565b600060208284031215613cb657600080fd5b61365882613a8c565b600060208284031215613cd157600080fd5b5035919050565b600060208284031215613cea57600080fd5b5051919050565b600060208284031215613d0357600080fd5b81356001600160401b03811115613d1957600080fd5b613d2584828501613a9c565b949350505050565b60008060408385031215613d4057600080fd5b82356001600160401b03811115613d5657600080fd5b613d6285828601613a9c565b95602094909401359450505050565b60008060408385031215613d8457600080fd5b8235613d8f8161459d565b946020939093013593505050565b600080600080600080600060e0888a031215613db857600080fd5b8735613dc38161459d565b965060208881013596506040890135613ddb8161459d565b95506060890135945060808901356001600160401b0380821115613dfe57600080fd5b613e0a8c838d01613a2c565b955060a08b0135915080821115613e2057600080fd5b508901601f81018b13613e3257600080fd5b8035613e406139d28261445a565b8082825284820191508484018e868560051b8701011115613e6057600080fd5b600094505b83851015613e8c578035613e788161459d565b835260019490940193918501918501613e65565b508096505050505050613ea160c089016139a1565b905092959891949750929550565b60008060008060008060c08789031215613ec857600080fd5b8635613ed38161459d565b9550602087013594506040870135613eea8161459d565b9350606087013592506080870135915060a0870135613f088161459d565b809150509295509295509295565b60006020808385031215613f2957600080fd5b82516001600160401b0380821115613f4057600080fd5b9084019060608287031215613f5457600080fd5b613f5c614402565b825182811115613f6b57600080fd5b83019150601f82018713613f7e57600080fd5b8151613f8c6139d28261447d565b8181528886838601011115613fa057600080fd5b613faf82878301888701614514565b825250613fbd838501613a8c565b84820152613fcd60408401613aed565b60408201529695505050505050565b60008060408385031215613fef57600080fd5b8235915060208301356140018161459d565b809150509250929050565b6000806040838503121561401f57600080fd5b8251915060208301516140018161459d565b600081518084526020808501945080840160005b8381101561406a5781516001600160a01b031687529582019590820190600101614045565b509495945050505050565b600081518084526020808501945080840160005b8381101561406a57815187529582019590820190600101614089565b600082516140b7818460208701614514565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03958616815293909416602084015260408301919091526060820152608081019190915260a00190565b6040815260006141196040830185614075565b828103602084015261412b8185614031565b95945050505050565b6060815260006141476060830186614075565b82810360208401526141598186614031565b915050826040830152949350505050565b60608152600061417d6060830186614075565b82810360208401526141598186614075565b6001600160a01b0392831681529116602082015260400190565b60208152600082518060208401526141c8816040850160208701614514565b601f01601f19169190910160400192915050565b6020808252602a908201527f57617264656e537761703a20457468657220736f7572636520616d6f756e74206040820152691b5a5cdb585d18da195960b21b606082015260800190565b60208082526030908201527f57617264656e537761703a20736f7572636520616d6f756e74206d69736d617460408201526f6368656420616674657220747261646560801b606082015260800190565b60208082526031908201527f57617264656e537761703a205472616e73666572206574686572206261636b206040820152703a379031b0b63632b9103330b4b632b21760791b606082015260800190565b6020808252602a908201527f57617264656e537761703a2064657374696e6174696f6e20616d6f756e74206960408201526939903a37b7903637bb9760b11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526035908201527f57617264656e537761703a2064657374696e6174696f6e20616d6f756e74206d60408201527469736d61746368656420616674657220747261646560581b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b94855260208501939093526001600160a01b03919091166040840152151560608301521515608082015260a00190565b604051606081016001600160401b038111828210171561442457614424614587565b60405290565b604051601f8201601f191681016001600160401b038111828210171561445257614452614587565b604052919050565b60006001600160401b0382111561447357614473614587565b5060051b60200190565b60006001600160401b0382111561449657614496614587565b50601f01601f191660200190565b600082198211156144b7576144b761455b565b500190565b6000826144d957634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156144f8576144f861455b565b500290565b60008282101561450f5761450f61455b565b500390565b60005b8381101561452f578181015183820152602001614517565b8381111561236b5750506000910152565b60006000198214156145545761455461455b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146119ef57600080fdfe7acb84937815db1a71622c24a8f03661982c6ac39f087563b5033ab1c9d2cbbd000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeea26469706673582212203fe43e9d5767501c95f9d4f08d2775fa221c770fb1d3221f7d124546bb927e6464736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001a5f88fb85bd2b5eb1b5dc738ae02a5f0a69729f000000000000000000000000ac8b2026587e2e9f83f066cd302b1b71dc41f6e300000000000000000000000071ac17934b60a4610dc58b715b61e45dcbde405400000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab10000000000000000000000000000000000000000000000000000000000000066
-----Decoded View---------------
Arg [0] : _cosmoCore (address): 0x1A5F88FB85BD2B5eB1b5dc738Ae02A5f0A69729f
Arg [1] : _cosmicBrain (address): 0xaC8b2026587e2E9f83f066CD302b1B71dC41f6E3
Arg [2] : _postTrade (address): 0x71ac17934b60A4610dc58b715B61e45DCBdE4054
Arg [3] : _weth (address): 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1
Arg [4] : _addressTable (address): 0x0000000000000000000000000000000000000066
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000001a5f88fb85bd2b5eb1b5dc738ae02a5f0a69729f
Arg [1] : 000000000000000000000000ac8b2026587e2e9f83f066cd302b1b71dc41f6e3
Arg [2] : 00000000000000000000000071ac17934b60a4610dc58b715b61e45dcbde4054
Arg [3] : 00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000066
Deployed Bytecode Sourcemap
89512:9830:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71204:209;;;;;;;;;;-1:-1:-1;71204:209:0;;;;;:::i;:::-;;:::i;:::-;;33342:2173;;;;;;;;;;-1:-1:-1;33342:2173:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;32894:436;;;;;;;;;;-1:-1:-1;32894:436:0;;;;;:::i;:::-;;:::i;:::-;;;;32673:25:1;;;32729:2;32714:18;;32707:34;;;;32757:18;;;32750:34;32661:2;32646:18;32894:436:0;32471:319:1;38598:1745:0;;;;;;;;;;-1:-1:-1;38598:1745:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;14500:15:1;;;14482:34;;14552:15;;;14547:2;14532:18;;14525:43;14604:15;;14599:2;14584:18;;14577:43;14651:2;14636:18;;14629:34;;;;14431:3;14416:19;;14213:456;69009:33:0;;;;;;;;;;-1:-1:-1;69009:33:0;;;;-1:-1:-1;;;;;69009:33:0;;;;;;;;;;:::i;91575:1157::-;;;;;;:::i;:::-;;:::i;:::-;;;17601:25:1;;;17589:2;17574:18;91575:1157:0;17455:177:1;84130:1691:0;;;;;;:::i;:::-;;:::i;93827:576::-;;;;;;:::i;:::-;;:::i;87433:186::-;;;;;;;;;;-1:-1:-1;87433:186:0;;;;;:::i;:::-;;:::i;95332:853::-;;;;;;:::i;:::-;;:::i;68925:33::-;;;;;;;;;;-1:-1:-1;68925:33:0;;;;-1:-1:-1;;;;;68925:33:0;;;96197:940;;;;;;:::i;:::-;;:::i;97149:1130::-;;;;;;:::i;:::-;;:::i;90622:941::-;;;;;;:::i;:::-;;:::i;98291:1048::-;;;;;;:::i;:::-;;:::i;86646:642::-;;;;;;;;;;-1:-1:-1;86646:642:0;;;;;:::i;:::-;;:::i;70973:219::-;;;;;;;;;;-1:-1:-1;70973:219:0;;;;;:::i;:::-;;:::i;70750:211::-;;;;;;;;;;-1:-1:-1;70750:211:0;;;;;:::i;:::-;;:::i;65369:94::-;;;;;;;;;;;;;:::i;78590:643::-;;;;;;:::i;:::-;;:::i;32393:489::-;;;;;;;;;;-1:-1:-1;32393:489:0;;;;;:::i;:::-;;:::i;:::-;;;;33026:25:1;;;33082:2;33067:18;;33060:34;;;;33110:18;;;33103:34;33168:2;33153:18;;33146:34;33013:3;32998:19;32393:489:0;32795:391:1;94415:905:0;;;;;;:::i;:::-;;:::i;64718:87::-;;;;;;;;;;;;;:::i;87764:284::-;;;;;;;;;;-1:-1:-1;87764:284:0;;;;;:::i;:::-;;:::i;68965:37::-;;;;;;;;;;-1:-1:-1;68965:37:0;;;;-1:-1:-1;;;;;68965:37:0;;;90042:568;;;;;;;;;;-1:-1:-1;90042:568:0;;;;;:::i;:::-;;:::i;28993:729::-;;;;;;;;;;-1:-1:-1;28993:729:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;79635:838::-;;;;;;:::i;:::-;;:::i;85992:434::-;;;;;;:::i;:::-;;:::i;35527:1673::-;;;;;;;;;;-1:-1:-1;35527:1673:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;29734:719::-;;;;;;;;;;-1:-1:-1;29734:719:0;;;;;:::i;:::-;;:::i;92744:1071::-;;;;;;:::i;:::-;;:::i;65618:192::-;;;;;;;;;;-1:-1:-1;65618:192:0;;;;;:::i;:::-;;:::i;71204:209::-;63533:10;64938:7;:5;:7::i;:::-;-1:-1:-1;;;;;64938:23:0;;64930:68;;;;-1:-1:-1;;;64930:68:0;;;;;;;:::i;:::-;;;;;;;;;71333:9:::1;:22:::0;;-1:-1:-1;;;;;;71333:22:0::1;-1:-1:-1::0;;;;;71333:22:0;::::1;::::0;;::::1;::::0;;;71371:34:::1;::::0;::::1;::::0;-1:-1:-1;;71371:34:0::1;71204:209:::0;:::o;33342:2173::-;33513:29;;33638;;34698:22;:5;34712:7;34698:13;:22::i;:::-;34677:43;-1:-1:-1;34731:12:0;34742:1;34731:12;;:::i;:::-;;-1:-1:-1;34764:19:0;;34801:4;34786:19;;;34847:1;34831:17;;;34786:19;-1:-1:-1;;;;;34990:26:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34990:26:0;-1:-1:-1;34977:39:0;-1:-1:-1;35063:15:0;35077:1;35063:11;:15;:::i;:::-;-1:-1:-1;;;;;35050:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35050:29:0;;35027:52;;35105:9;35100:135;35124:11;35120:1;:15;35100:135;;;35173:23;:5;35188:7;35173:14;:23::i;:::-;35157:39;;:10;35168:1;35157:13;;;;;;;;:::i;:::-;;;;;;;;;;:39;35211:12;35222:1;35211:12;;:::i;:::-;;-1:-1:-1;35137:3:0;;;;:::i;:::-;;;;35100:135;;;;35260:9;35255:222;35279:15;35293:1;35279:11;:15;:::i;:::-;35275:1;:19;35255:222;;;35316:13;35363:48;35378:16;35396:5;35403:7;35363:14;:48::i;:::-;35344:67;;;;;;;;35459:5;35426:20;35447:1;35426:23;;;;;;;;:::i;:::-;-1:-1:-1;;;;;35426:39:0;;;:23;;;;;;;;;;;:39;-1:-1:-1;35296:3:0;;;;:::i;:::-;;;;35255:222;;;;35500:7;35487:20;;33684:1831;;;33342:2173;;;;;:::o;32894:436::-;33047:18;33080:22;33117:18;33271:51;33301:5;33308:7;33317:4;33271:29;:51::i;:::-;33163:159;;;;-1:-1:-1;33163:159:0;;-1:-1:-1;32894:436:0;-1:-1:-1;;;;32894:436:0:o;38598:1745::-;38762:12;;;;;39688:22;:5;39702:7;39688:13;:22::i;:::-;39667:43;-1:-1:-1;39721:12:0;39732:1;39721:12;;:::i;:::-;;-1:-1:-1;39792:4:0;40040:17;;;;;;;39777:19;;;;39838:1;39822:17;;;39884:19;;;39929:17;;39995:19;40096:46;39777:19;40127:5;39721:12;40096:14;:46::i;:::-;40078:64;-1:-1:-1;40078:64:0;-1:-1:-1;40172:47:0;40187:15;40204:5;40078:64;40172:14;:47::i;:::-;40153:66;-1:-1:-1;40153:66:0;-1:-1:-1;40253:51:0;40268:19;40289:5;40153:66;40253:14;:51::i;:::-;38598:1745;;;;-1:-1:-1;40230:74:0;-1:-1:-1;;;;;;;38598:1745:0:o;91575:1157::-;91690:19;;;;;91949:30;91965:5;91690:19;91949:15;:30::i;:::-;91854:125;-1:-1:-1;91854:125:0;;-1:-1:-1;91854:125:0;-1:-1:-1;91854:125:0;-1:-1:-1;92030:17:0;;92177:34;92197:5;91854:125;92177:19;:34::i;:::-;92090:121;-1:-1:-1;92090:121:0;;-1:-1:-1;92090:121:0;-1:-1:-1;92259:28:0;;92440:52;92478:5;92090:121;92440:37;:52::i;:::-;92347:145;-1:-1:-1;92347:145:0;;-1:-1:-1;92347:145:0;-1:-1:-1;92512:212:0;92549:3;92568:9;92599:4;92619:13;92347:145;;92705:8;92512:15;:212::i;:::-;92505:219;91575:1157;-1:-1:-1;;;;;;;;;;91575:1157:0:o;84130:1691::-;84509:19;67798:1;68394:7;;:19;;68386:63;;;;-1:-1:-1;;;68386:63:0;;;;;;;:::i;:::-;67798:1;68527:7;:18;84554;;84546:74:::1;;;::::0;-1:-1:-1;;;84546:74:0;;21449:2:1;84546:74:0::1;::::0;::::1;21431:21:1::0;21488:2;21468:18;;;21461:30;21527:34;21507:18;;;21500:62;-1:-1:-1;;;21578:18:1;;;21571:37;21625:19;;84546:74:0::1;21247:403:1::0;84546:74:0::1;84661:8;:15;84639:11;:18;:37;84631:103;;;::::0;-1:-1:-1;;;84631:103:0;;25321:2:1;84631:103:0::1;::::0;::::1;25303:21:1::0;25360:2;25340:18;;;25333:30;25399:34;25379:18;;;25372:62;-1:-1:-1;;;25450:18:1;;;25443:51;25511:19;;84631:103:0::1;25119:417:1::0;84631:103:0::1;84769:154;84809:11;84835:8;84858:4;84877:15;84907:5;84769:25;:154::i;:::-;84755:168;;84982:197;85020:4;85039:5;85059:15;85089:11;85115:10;85140:9;85164:4;84982:23;:197::i;:::-;84968:211;;85296:14;85281:11;:29;;85273:84;;;;-1:-1:-1::0;;;85273:84:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;;;;;;;;;;;85372:20:0;::::1;;85368:327;;;85410:12;85428:9;-1:-1:-1::0;;;;;85428:14:0::1;85450:11;85428:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85409:57;;;85518:7;85510:69;;;;-1:-1:-1::0;;;85510:69:0::1;;;;;;;:::i;:::-;85394:197;85368:327;;;85641:42;-1:-1:-1::0;;;;;85641:18:0;::::1;85660:9:::0;85671:11;85641:18:::1;:42::i;:::-;85779:10;-1:-1:-1::0;;;;;85712:101:0::1;85758:5;-1:-1:-1::0;;;;;85712:101:0::1;85726:4;-1:-1:-1::0;;;;;85712:101:0::1;-1:-1:-1::0;;;;;;;;;;;85733:15:0::1;85766:11;85791:9;85802:4;85808::::0;85712:101:::1;;;;;;;;;;:::i;:::-;;;;;;;;67754:1:::0;68706:22;;84130:1691;;-1:-1:-1;;;;;;;84130:1691:0:o;93827:576::-;93948:19;94000:11;94026:12;94053:17;94085:21;94121:17;94152:34;94170:15;94152:17;:34::i;:::-;93985:201;;;;;;;;;;94214:181;94252:3;94271:9;94302:4;94322:13;94350:9;94374:10;94214:16;:181::i;:::-;94207:188;93827:576;-1:-1:-1;;;;;;;93827:576:0:o;87433:186::-;63533:10;64938:7;:5;:7::i;:::-;-1:-1:-1;;;;;64938:23:0;;64930:68;;;;-1:-1:-1;;;64930:68:0;;;;;;;:::i;:::-;87571:40:::1;-1:-1:-1::0;;;;;87571:19:0;::::1;87591:10;87603:7:::0;87571:19:::1;:40::i;:::-;87433:186:::0;;:::o;95332:853::-;95448:19;;;;;95683:30;95699:5;95448:19;95683:15;:30::i;:::-;95588:125;-1:-1:-1;95588:125:0;;-1:-1:-1;95588:125:0;-1:-1:-1;95588:125:0;-1:-1:-1;95734:17:0;95754:23;:5;95588:125;95754:15;:23::i;:::-;95734:43;-1:-1:-1;95788:12:0;95798:2;95788:12;;:::i;:::-;;-1:-1:-1;95821:21:0;95845:23;:5;95788:12;95845:15;:23::i;:::-;95821:47;-1:-1:-1;95879:12:0;95889:2;95879:12;;:::i;:::-;;-1:-1:-1;95904:17:0;95924:23;:5;95879:12;95924:15;:23::i;:::-;95904:43;-1:-1:-1;95958:12:0;95968:2;95958:12;;:::i;:::-;;;95998:179;96036:3;96055:9;96086:4;96106:13;96134:9;96158:8;95998:16;:179::i;:::-;95991:186;95332:853;-1:-1:-1;;;;;;;;;95332:853:0:o;96197:940::-;96308:19;;;;;;96615:32;96633:5;96308:19;96615:17;:32::i;:::-;96486:161;-1:-1:-1;96486:161:0;;-1:-1:-1;96486:161:0;;-1:-1:-1;96486:161:0;-1:-1:-1;96486:161:0;-1:-1:-1;96701:27:0;;96856:41;96883:5;96486:161;96856:26;:41::i;:::-;96774:123;-1:-1:-1;96774:123:0;;-1:-1:-1;96774:123:0;-1:-1:-1;96925:204:0;96774:123;;97005:3;97024:14;97060:4;97080:13;97108:10;96925:11;:204::i;97149:1130::-;97260:19;;;;;97519:30;97535:5;97260:19;97519:15;:30::i;:::-;97424:125;-1:-1:-1;97424:125:0;;-1:-1:-1;97424:125:0;-1:-1:-1;97424:125:0;-1:-1:-1;97600:22:0;;97757:34;97777:5;97424:125;97757:19;:34::i;:::-;97665:126;-1:-1:-1;97665:126:0;;-1:-1:-1;97665:126:0;-1:-1:-1;97845:27:0;;98000:41;98027:5;97665:126;98000:26;:41::i;:::-;97918:123;-1:-1:-1;97918:123:0;;-1:-1:-1;97918:123:0;-1:-1:-1;98069:202:0;97918:123;;98149:3;98168:14;98204:4;98224:13;98252:8;98069:11;:202::i;90622:941::-;90738:19;;;;;;91035:32;91053:5;90738:19;91035:17;:32::i;:::-;90911:156;-1:-1:-1;90911:156:0;;-1:-1:-1;90911:156:0;;-1:-1:-1;90911:156:0;-1:-1:-1;90911:156:0;-1:-1:-1;91088:28:0;;91269:52;91307:5;90911:156;91269:37;:52::i;:::-;91176:145;-1:-1:-1;91176:145:0;;-1:-1:-1;91176:145:0;-1:-1:-1;91341:214:0;91378:3;91397:9;91428:4;91448:13;91176:145;;91534:10;91341:15;:214::i;98291:1048::-;98402:19;;;;;98638:30;98654:5;98402:19;98638:15;:30::i;:::-;98543:125;-1:-1:-1;98543:125:0;;-1:-1:-1;98543:125:0;-1:-1:-1;98543:125:0;-1:-1:-1;98689:22:0;98714:23;:5;98543:125;98714:15;:23::i;:::-;98689:48;-1:-1:-1;98748:12:0;98758:2;98748:12;;:::i;:::-;;-1:-1:-1;98781:21:0;98805:23;:5;98748:12;98805:15;:23::i;:::-;98781:47;-1:-1:-1;98839:12:0;98849:2;98839:12;;:::i;:::-;;;98905:27;98943:24;99060:41;99087:5;99094:6;99060:26;:41::i;86646:642::-;86799:19;67798:1;68394:7;;:19;;68386:63;;;;-1:-1:-1;;;68386:63:0;;;;;;;:::i;:::-;67798:1;68527:7;:18;86836:77:::1;-1:-1:-1::0;;;;;86851:4:0::1;86836:38;86875:10;86895:4;86902:10:::0;86836:38:::1;:77::i;:::-;86924:25;::::0;-1:-1:-1;;;86924:25:0;;::::1;::::0;::::1;17601::1::0;;;86924:4:0::1;-1:-1:-1::0;;;;;86924:13:0::1;::::0;::::1;::::0;17574:18:1;;86924:25:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;86961:12;86979:9;-1:-1:-1::0;;;;;86979:14:0::1;87001:10;86979:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86960:56;;;87064:7;87056:69;;;;-1:-1:-1::0;;;87056:69:0::1;;;;;;;:::i;:::-;87150:10;87136:24;;87244:10;-1:-1:-1::0;;;;;87176:104:0::1;-1:-1:-1::0;;;;;;;;;;;;;;;;87176:104:0::1;87190:4;-1:-1:-1::0;;;;;87176:104:0::1;-1:-1:-1::0;;;;;;;;;;;87197:10:0::1;87231:11;87256:9;87267:5;87274::::0;87176:104:::1;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;67754:1:0;68706:22;;86646:642;;-1:-1:-1;;86646:642:0:o;70973:219::-;63533:10;64938:7;:5;:7::i;:::-;-1:-1:-1;;;;;64938:23:0;;64930:68;;;;-1:-1:-1;;;64930:68:0;;;;;;;:::i;:::-;71104:11:::1;:26:::0;;-1:-1:-1;;;;;;71104:26:0::1;-1:-1:-1::0;;;;;71104:26:0;::::1;::::0;;::::1;::::0;;;71146:38:::1;::::0;::::1;::::0;-1:-1:-1;;71146:38:0::1;70973:219:::0;:::o;70750:211::-;63533:10;64938:7;:5;:7::i;:::-;-1:-1:-1;;;;;64938:23:0;;64930:68;;;;-1:-1:-1;;;64930:68:0;;;;;;;:::i;:::-;70881:9:::1;:22:::0;;-1:-1:-1;;;;;;70881:22:0::1;-1:-1:-1::0;;;;;70881:22:0;::::1;::::0;;::::1;::::0;;;70919:34:::1;::::0;::::1;::::0;-1:-1:-1;;70919:34:0::1;70750:211:::0;:::o;65369:94::-;63533:10;64938:7;:5;:7::i;:::-;-1:-1:-1;;;;;64938:23:0;;64930:68;;;;-1:-1:-1;;;64930:68:0;;;;;;;:::i;:::-;65434:21:::1;65452:1;65434:9;:21::i;:::-;65369:94::o:0;78590:643::-;78941:19;67798:1;68394:7;;:19;;68386:63;;;;-1:-1:-1;;;68386:63:0;;;;;;;:::i;:::-;67798:1;68527:7;:18;78992:233:::1;79036:4:::0;79055:10;79080:5;79100:14;79129:10;79154:20;79189:9;79213:1:::1;78992:29;:233::i;:::-;67754:1:::0;68706:22;;78978:247;78590:643;-1:-1:-1;;;;;;;;78590:643:0:o;32393:489::-;32555:18;32588:22;32625:18;32658;32822:52;32852:5;32859:7;32868:5;32822:29;:52::i;:::-;32704:170;;;;-1:-1:-1;32704:170:0;-1:-1:-1;32704:170:0;;-1:-1:-1;32393:489:0;-1:-1:-1;;;32393:489:0:o;94415:905::-;94531:19;;;;;94790:30;94806:5;94531:19;94790:15;:30::i;:::-;94695:125;-1:-1:-1;94695:125:0;;-1:-1:-1;94695:125:0;-1:-1:-1;94695:125:0;-1:-1:-1;94863:17:0;;;95062:43;95091:5;94695:125;95062:28;:43::i;:::-;94951:154;-1:-1:-1;94951:154:0;;-1:-1:-1;94951:154:0;-1:-1:-1;94951:154:0;-1:-1:-1;95133:179:0;95171:3;94951:154;95221:4;94951:154;;95293:8;95133:16;:179::i;64718:87::-;64764:7;64791:6;-1:-1:-1;;;;;64791:6:0;;64718:87::o;87764:284::-;63533:10;64938:7;:5;:7::i;:::-;-1:-1:-1;;;;;64938:23:0;;64930:68;;;;-1:-1:-1;;;64930:68:0;;;;;;;:::i;:::-;87896:35:::1;::::0;87878:12:::1;::::0;87896:10:::1;::::0;87919:7;;87878:12;87896:35;87878:12;87896:35;87919:7;87896:10;:35:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87877:54;;;87979:7;87971:69;;;;-1:-1:-1::0;;;87971:69:0::1;;;;;;;:::i;90042:568::-:0;90191:12;90218:13;90246:17;90278:18;90426:46;90457:5;90464:7;90426:30;:46::i;:::-;90324:148;;-1:-1:-1;90324:148:0;;-1:-1:-1;90324:148:0;-1:-1:-1;90324:148:0;-1:-1:-1;;;;;;90497:55:0;;90493:110;;90581:10;90569:22;;90493:110;90042:568;;;;;;;:::o;28993:729::-;29113:12;29140:13;29168:18;29201:22;29238:18;29284:17;29304:14;29312:5;29304:7;:14::i;:::-;29284:34;;29331:16;29358:17;29541:33;29559:4;29565:1;29568:5;29541:17;:33::i;:::-;-1:-1:-1;29626:34:0;;-1:-1:-1;;;29626:34:0;;;;;17601:25:1;;;29386:188:0;;-1:-1:-1;29386:188:0;;-1:-1:-1;29386:188:0;-1:-1:-1;29386:188:0;;-1:-1:-1;29386:188:0;-1:-1:-1;29626:12:0;-1:-1:-1;;;;;29626:24:0;;;;17574:18:1;;29626:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29679:35;;-1:-1:-1;;;29679:35:0;;;;;17601:25:1;;;29619:41:0;;-1:-1:-1;29679:12:0;-1:-1:-1;;;;;29679:24:0;;;;17574:18:1;;29679:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29671:43;;29273:449;;;28993:729;;;;;;;:::o;79635:838::-;79918:19;67798:1;68394:7;;:19;;68386:63;;;;-1:-1:-1;;;68386:63:0;;;;;;;:::i;:::-;67798:1;68527:7;:18;79977:11:::1;::::0;:37:::1;::::0;-1:-1:-1;;;79977:37:0;;::::1;::::0;::::1;17601:25:1::0;;;79955:19:0::1;::::0;-1:-1:-1;;;;;79977:11:0::1;::::0;:25:::1;::::0;17574:18:1;;79977:37:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80145:11;::::0;:45:::1;::::0;-1:-1:-1;;;80145:45:0;;::::1;::::0;::::1;17601:25:1::0;;;79955:59:0;;-1:-1:-1;80050:28:0::1;::::0;;;-1:-1:-1;;;;;80145:11:0::1;::::0;:32:::1;::::0;17574:18:1;;80145:45:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;80145:45:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;80035:155;;;;80225:240;80269:4;80288:10;80313:5;80333:14;80362:9;80386:19;80420:9;80444:10;80225:29;:240::i;:::-;67754:1:::0;68706:22;;80211:254;79635:838;-1:-1:-1;;;;;;;;;;79635:838:0:o;85992:434::-;86129:19;67798:1;68394:7;;:19;;68386:63;;;;-1:-1:-1;;;68386:63:0;;;;;;;:::i;:::-;67798:1;68527:7;:18;;;;86166:4:::1;-1:-1:-1::0;;;;;86166:12:0::1;;86186:9;86166:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;86209:56:0::1;::::0;-1:-1:-1;;;;;;;86224:4:0::1;86209:34;::::0;-1:-1:-1;86244:9:0;;-1:-1:-1;86255:9:0::1;86209:34;:56::i;:::-;86290:9;86276:23;;86382:10;-1:-1:-1::0;;;;;86315:103:0::1;86362:4;-1:-1:-1::0;;;;;86315:103:0::1;-1:-1:-1::0;;;;;;;;;;;;;;;;86315:103:0::1;-1:-1:-1::0;;;;;;;;;;;86343:9:0::1;86369:11;86394:9;86405:5;86412::::0;86315:103:::1;;;;;;;;;;:::i;:::-;;;;;;;;67754:1:::0;68706:22;;85992:434;;-1:-1:-1;85992:434:0:o;35527:1673::-;35687:30;;35797:29;;36276:22;:5;36290:7;36276:13;:22::i;:::-;36255:43;-1:-1:-1;36309:12:0;36320:1;36309:12;;:::i;:::-;;-1:-1:-1;36491:4:0;36521:17;;;;;;;36379:4;36364:19;;;36425:1;36409:17;;;;36476:19;36364;-1:-1:-1;;;;;36604:26:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36604:26:0;;36590:40;;36646:9;36641:151;36665:11;36661:1;:15;36641:151;;;36726:54;36743:20;36765:5;36772:7;36726:16;:54::i;:::-;36699:11;36711:1;36699:14;;;;;;;;:::i;:::-;;;;;;36698:82;;;;;;;;;36678:3;;;;;:::i;:::-;;;;36641:151;;;;36871:11;-1:-1:-1;;;;;36857:26:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36857:26:0;-1:-1:-1;36846:37:0;-1:-1:-1;36917:3:0;36894:20;36931:178;36955:15;36969:1;36955:11;:15;:::i;:::-;36951:1;:19;36931:178;;;37006:22;:5;37020:7;37006:13;:22::i;:::-;36992:36;;:8;37001:1;36992:11;;;;;;;;:::i;:::-;;;;;;;;;;:36;37043:12;37054:1;37043:12;;:::i;:::-;;;37086:8;37095:1;37086:11;;;;;;;;:::i;:::-;;;;;;;37070:27;;;;;:::i;:::-;;-1:-1:-1;36972:3:0;;;;:::i;:::-;;;;36931:178;;;-1:-1:-1;37147:12:0;37119:8;37128:15;37142:1;37128:11;:15;:::i;:::-;37119:25;;;;;;;;:::i;:::-;;;;;;:40;;;;;37185:7;37172:20;;35843:1357;;;;35527:1673;;;;;:::o;29734:719::-;29885:12;29912:13;29940:18;29973:22;30010:18;30056:16;30083:17;30266:39;30284:5;30291:7;30300:4;30266:17;:39::i;:::-;30357:34;;-1:-1:-1;;;30357:34:0;;;;;17601:25:1;;;30111:194:0;;-1:-1:-1;30111:194:0;;-1:-1:-1;30111:194:0;;-1:-1:-1;30111:194:0;;-1:-1:-1;30111:194:0;;-1:-1:-1;30357:12:0;-1:-1:-1;;;;;30357:24:0;;-1:-1:-1;30357:24:0;;17574:18:1;;30357:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30410:35;;-1:-1:-1;;;30410:35:0;;;;;17601:25:1;;;30350:41:0;;-1:-1:-1;30410:12:0;-1:-1:-1;;;;;30410:24:0;;;;17574:18:1;;30410:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;30402:43;;30045:408;;29734:719;;;;;;;;:::o;92744:1071::-;92859:19;;;;;93094:30;93110:5;92859:19;93094:15;:30::i;:::-;92999:125;-1:-1:-1;92999:125:0;;-1:-1:-1;92999:125:0;-1:-1:-1;92999:125:0;-1:-1:-1;93145:17:0;93165:23;:5;92999:125;93165:15;:23::i;:::-;93145:43;-1:-1:-1;93199:12:0;93209:2;93199:12;;:::i;:::-;;-1:-1:-1;93232:21:0;93256:23;:5;93199:12;93256:15;:23::i;:::-;93232:47;-1:-1:-1;93290:12:0;93300:2;93290:12;;:::i;:::-;;;93342:28;93381:38;93523:52;93561:5;93568:6;93523:37;:52::i;65618:192::-;63533:10;64938:7;:5;:7::i;:::-;-1:-1:-1;;;;;64938:23:0;;64930:68;;;;-1:-1:-1;;;64930:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;65707:22:0;::::1;65699:73;;;::::0;-1:-1:-1;;;65699:73:0;;22623:2:1;65699:73:0::1;::::0;::::1;22605:21:1::0;22662:2;22642:18;;;22635:30;22701:34;22681:18;;;22674:62;-1:-1:-1;;;22752:18:1;;;22745:36;22798:19;;65699:73:0::1;22421:402:1::0;65699:73:0::1;65783:19;65793:8;65783:9;:19::i;:::-;65618:192:::0;:::o;17615:311::-;17692:5;17735:10;:6;17744:1;17735:10;:::i;:::-;17718:6;:13;:27;;17710:60;;;;-1:-1:-1;;;17710:60:0;;29471:2:1;17710:60:0;;;29453:21:1;29510:2;29490:18;;;29483:30;-1:-1:-1;;;29529:18:1;;;29522:49;29588:18;;17710:60:0;29269:343:1;17710:60:0;-1:-1:-1;17850:29:0;17866:3;17850:29;17844:36;;17615:311::o;17934:314::-;18012:6;18056:10;:6;18065:1;18056:10;:::i;:::-;18039:6;:13;:27;;18031:60;;;;-1:-1:-1;;;18031:60:0;;23030:2:1;18031:60:0;;;23012:21:1;23069:2;23049:18;;;23042:30;-1:-1:-1;;;23088:18:1;;;23081:50;23148:18;;18031:60:0;22828:344:1;18031:60:0;-1:-1:-1;18172:29:0;18188:3;18172:29;18166:36;;17934:314::o;37212:1378::-;37411:16;;37808:17;;;37804:779;;37872:24;:5;37888:7;37872:15;:24::i;:::-;37860:36;-1:-1:-1;37924:12:0;:7;37934:2;37924:12;:::i;:::-;37911:25;;37804:779;;;37972:12;:17;;37988:1;37972:17;37968:615;;;-1:-1:-1;;;;;38040:12:0;:24;;38065:23;:5;38080:7;38065:14;:23::i;:::-;38040:49;;-1:-1:-1;;;;;;38040:49:0;;;;;;;;33354:23:1;;;;38040:49:0;;;33336:42:1;33309:18;;38040:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38029:60;-1:-1:-1;38117:11:0;:7;38127:1;38117:11;:::i;37968:615::-;38152:12;:17;;38168:1;38152:17;38148:435;;;-1:-1:-1;;;;;38220:12:0;:24;;38245:23;:5;38260:7;38245:14;:23::i;:::-;38220:49;;-1:-1:-1;;;;;;38220:49:0;;;;;;;31754:8:1;31742:21;;;38220:49:0;;;31724:40:1;31697:18;;38220:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;38209:60;-1:-1:-1;38297:11:0;:7;38307:1;38297:11;:::i;38148:435::-;38332:12;:17;;38348:1;38332:17;38328:255;;;-1:-1:-1;38385:42:0;;-1:-1:-1;38455:7:0;38328:255;;;38509:62;;-1:-1:-1;;;38509:62:0;;23379:2:1;38509:62:0;;;23361:21:1;23418:2;23398:18;;;23391:30;23457:34;23437:18;;;23430:62;-1:-1:-1;;;23508:18:1;;;23501:50;23568:19;;38509:62:0;23177:416:1;38328:255:0;37212:1378;;;;;;:::o;30465:1916::-;30658:18;;;;;31624:22;:5;31638:7;31624:13;:22::i;:::-;31603:43;-1:-1:-1;31657:12:0;31668:1;31657:12;;:::i;:::-;;-1:-1:-1;31764:17:0;31780:1;31764:17;;;;;31734:4;31719:19;31816:51;31719:19;31852:5;31657:12;31816:13;:51::i;:::-;31792:75;-1:-1:-1;31792:75:0;-1:-1:-1;31966:17:0;31982:1;31966:17;;;;;31936:4;31921:19;32022:55;31921:19;32062:5;31792:75;32022:13;:55::i;:::-;31994:83;-1:-1:-1;31994:83:0;-1:-1:-1;32103:13:0;32098:235;;32177:4;32211:17;;;;;;32162:19;32267:54;32162:19;32306:5;32313:7;32267:16;:54::i;:::-;32243:78;-1:-1:-1;32243:78:0;-1:-1:-1;;32098:235:0;32366:7;32353:20;;30796:1585;;;30465:1916;;;;;;;:::o;81886:1800::-;82156:19;;;-1:-1:-1;;;;;;;;;;;;;;;;82244:20:0;;;:52;;82291:5;82244:52;;;82282:4;82244:52;82222:74;-1:-1:-1;82307:19:0;-1:-1:-1;;;;;;;;;;;;;;;;82372:19:0;;;82368:384;;;82429:15;82416:9;:28;82408:83;;;;-1:-1:-1;;;82408:83:0;;;;;;;:::i;:::-;82506:4;-1:-1:-1;;;;;82506:12:0;;82526:15;82506:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82602:4;82573:35;;82645:4;82623:27;;82368:384;;;-1:-1:-1;82697:4:0;;-1:-1:-1;82730:10:0;82368:384;82861:34;;-1:-1:-1;;;82861:34:0;;82835:23;;-1:-1:-1;;;;;82861:21:0;;;;;:34;;82883:11;;82861:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82835:60;;82906:24;82933:12;-1:-1:-1;;;;;82933:22:0;;82964:4;82933:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82906:64;;83005:176;83027:11;83053:8;83076:11;83102:15;83132:12;83159:11;83005:7;:176::i;:::-;82991:190;-1:-1:-1;83320:33:0;83338:15;83320;:33;:::i;:::-;83282:34;;-1:-1:-1;;;83282:34:0;;-1:-1:-1;;;;;83282:21:0;;;;;:34;;83304:11;;83282:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:71;83274:132;;;;-1:-1:-1;;;83274:132:0;;;;;;;:::i;:::-;83466:30;83485:11;83466:16;:30;:::i;:::-;83425:37;;-1:-1:-1;;;83425:37:0;;-1:-1:-1;;;;;83425:22:0;;;;;:37;;83456:4;;83425:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:71;83417:137;;;;-1:-1:-1;;;83417:137:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;83604:20:0;;;83600:79;;;83641:26;;-1:-1:-1;;;83641:26:0;;;;;17601:25:1;;;83641:4:0;-1:-1:-1;;;;;83641:13:0;;;;17574:18:1;;83641:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83600:79;82182:1504;;;;;81886:1800;;;;;;;:::o;88151:777::-;88540:9;;;:195;;-1:-1:-1;;;88540:195:0;;-1:-1:-1;;;;;18862:15:1;;;88540:195:0;;;18844:34:1;;;;18914:15;;;18894:18;;;18887:43;18946:18;;;18939:34;;;18989:18;;;18982:34;;;19053:15;;;19032:19;;;19025:44;19106:15;;;19085:19;;;19078:44;19166:14;;19159:22;19138:19;;;19131:51;88441:22:0;;;;;;88540:9;;;:25;;18778:19:1;;88540:195:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88505:230;;-1:-1:-1;88505:230:0;-1:-1:-1;88750:7:0;;88746:140;;88774:100;88804:5;88828:3;88850:9;88774:11;:100::i;:::-;88903:17;88917:3;88903:11;:17;:::i;59480:211::-;59624:58;;-1:-1:-1;;;;;15770:32:1;;59624:58:0;;;15752:51:1;15819:18;;;15812:34;;;59597:86:0;;59617:5;;-1:-1:-1;;;59647:23:0;15725:18:1;;59624:58:0;;;;-1:-1:-1;;59624:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;59624:58:0;-1:-1:-1;;;;;;59624:58:0;;;;;;;;;;59597:19;:86::i;:::-;59480:211;;;:::o;20535:320::-;20614:7;20659:11;:6;20668:2;20659:11;:::i;:::-;20642:6;:13;:28;;20634:62;;;;-1:-1:-1;;;20634:62:0;;26511:2:1;20634:62:0;;;26493:21:1;26550:2;26530:18;;;26523:30;-1:-1:-1;;;26569:18:1;;;26562:51;26630:18;;20634:62:0;26309:345:1;20634:62:0;-1:-1:-1;20778:30:0;20794:4;20778:30;20772:37;;20535:320::o;59699:248::-;59870:68;;-1:-1:-1;;;;;14932:15:1;;;59870:68:0;;;14914:34:1;14984:15;;14964:18;;;14957:43;15016:18;;;15009:34;;;59843:96:0;;59863:5;;-1:-1:-1;;;59893:27:0;14849:18:1;;59870:68:0;14674:375:1;59843:96:0;59699:248;;;;:::o;65818:173::-;65874:16;65893:6;;-1:-1:-1;;;;;65910:17:0;;;-1:-1:-1;;;;;;65910:17:0;;;;;;65943:40;;65893:6;;;;;;;65943:40;;65874:16;65943:40;65863:128;65818:173;:::o;74729:3392::-;75089:19;75159:20;:27;75154:1;75134:10;:17;:21;;;;:::i;:::-;:52;75126:112;;;;-1:-1:-1;;;75126:112:0;;23800:2:1;75126:112:0;;;23782:21:1;23839:2;23819:18;;;23812:30;23878:34;23858:18;;;23851:62;-1:-1:-1;;;23929:18:1;;;23922:45;23984:19;;75126:112:0;23598:411:1;75126:112:0;75264:18;;-1:-1:-1;;;;;;;;;;;;;;;;75319:20:0;;;:52;;75366:5;75319:52;;;75357:4;75319:52;75297:74;-1:-1:-1;75386:19:0;-1:-1:-1;;;;;;;;;;;;;;;;75463:19:0;;;75459:410;;;75524:10;75511:9;:23;75503:78;;;;-1:-1:-1;;;75503:78:0;;;;;;;:::i;:::-;75600:4;-1:-1:-1;;;;;75600:12:0;;75620:10;75600:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75699:4;75670:35;;75746:4;75724:27;;75459:410;;;-1:-1:-1;75806:4:0;;-1:-1:-1;75843:10:0;75459:410;75986:34;;-1:-1:-1;;;75986:34:0;;75960:23;;-1:-1:-1;;;;;75986:21:0;;;;;:34;;76008:11;;75986:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75960:60;;76035:24;76062:12;-1:-1:-1;;;;;76062:22:0;;76093:4;76062:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76035:64;;76142:219;76177:11;76207:10;76236:12;76267:10;76296:20;76335:11;76142:16;:219::i;:::-;76128:233;-1:-1:-1;76516:28:0;76534:10;76516:15;:28;:::i;:::-;76478:34;;-1:-1:-1;;;76478:34:0;;-1:-1:-1;;;;;76478:21:0;;;;;:34;;76500:11;;76478:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:66;76470:127;;;;-1:-1:-1;;;76470:127:0;;;;;;;:::i;:::-;76661:30;76680:11;76661:16;:30;:::i;:::-;76620:37;;-1:-1:-1;;;76620:37:0;;-1:-1:-1;;;;;76620:22:0;;;;;:37;;76651:4;;76620:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:71;76612:137;;;;-1:-1:-1;;;76612:137:0;;;;;;;:::i;:::-;75249:1512;;;;;76825:5;-1:-1:-1;;;;;76810:20:0;-1:-1:-1;;;;;;;;;;;;;;;;76810:20:0;;76806:79;;;76847:26;;-1:-1:-1;;;76847:26:0;;;;;17601:25:1;;;76847:4:0;-1:-1:-1;;;;;76847:13:0;;;;17574:18:1;;76847:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76806:79;76943:193;76981:4;77000:5;77020:10;77045:11;77071:10;77096:9;77120:5;76943:23;:193::i;:::-;76929:207;;77253:14;77238:11;:29;;77230:84;;;;-1:-1:-1;;;77230:84:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;77329:20:0;;;77325:327;;;77367:12;77385:9;-1:-1:-1;;;;;77385:14:0;77407:11;77385:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77366:57;;;77475:7;77467:69;;;;-1:-1:-1;;;77467:69:0;;;;;;;:::i;:::-;77351:197;77325:327;;;77598:42;-1:-1:-1;;;;;77598:18:0;;77617:9;77628:11;77598:18;:42::i;:::-;77692:10;77717:15;77713:111;;77761:11;;:51;;-1:-1:-1;;;77761:51:0;;-1:-1:-1;;;;;77761:11:0;;;;:17;;:51;;77779:10;;77791:20;;77761:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77749:63;;77713:111;77834:11;;:153;;-1:-1:-1;;;77834:153:0;;-1:-1:-1;;;;;77834:11:0;;;;:28;;:153;;77877:4;;77896:5;;77916:10;;77941:11;;77967:9;;77834:153;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;78067:10;-1:-1:-1;;;;;78005:108:0;78046:5;-1:-1:-1;;;;;78005:108:0;78019:4;-1:-1:-1;;;;;78005:108:0;-1:-1:-1;;;;;;;;;;;78026:10:0;78054:11;78079:9;78095:10;78090:1;:15;;78107:5;78005:108;;;;;;;;;;:::i;:::-;;;;;;;;75115:3006;74729:3392;;;;;;;;;;:::o;27292:117::-;27346:12;27395:5;27378:23;;;;;;13458:19:1;;13502:2;13493:12;;13329:182;27378:23:0;;;;;;;;;;;;;27371:30;;27292:117;;;:::o;27417:1564::-;27597:17;;;;;;28510:23;:5;28525:7;28510:14;:23::i;:::-;28498:35;;;-1:-1:-1;28544:12:0;28555:1;28544:12;;:::i;:::-;;-1:-1:-1;28590:23:0;:5;28544:12;28590:14;:23::i;:::-;28577:36;;;-1:-1:-1;28624:12:0;28635:1;28624:12;;:::i;:::-;;-1:-1:-1;28670:23:0;:5;28624:12;28670:14;:23::i;:::-;-1:-1:-1;;;;;28657:36:0;;-1:-1:-1;28704:13:0;28715:2;28704:13;;:::i;:::-;;-1:-1:-1;28755:23:0;:5;28704:13;28755:14;:23::i;:::-;-1:-1:-1;;;;;28738:40:0;;-1:-1:-1;28789:13:0;28800:2;28789:13;;:::i;:::-;;;28828;28823:110;;28871:23;:5;28886:7;28871:14;:23::i;:::-;28858:36;;;-1:-1:-1;28909:12:0;28920:1;28909:12;;:::i;:::-;;;28823:110;-1:-1:-1;27417:1564:0;;;;-1:-1:-1;27417:1564:0;;;;-1:-1:-1;28966:7:0;27417:1564::o;41789:856::-;41990:18;;42215:17;;;42211:427;;42289:23;:5;42304:7;42289:14;:23::i;:::-;42276:36;;;-1:-1:-1;42340:11:0;:7;42350:1;42340:11;:::i;42211:427::-;42387:12;:17;;42403:1;42387:17;42383:255;;;42465:23;:5;42480:7;42465:14;:23::i;:::-;42452:36;;;-1:-1:-1;42516:11:0;:7;42526:1;42516:11;:::i;42383:255::-;42562:64;;-1:-1:-1;;;42562:64:0;;27982:2:1;42562:64:0;;;27964:21:1;28021:2;28001:18;;;27994:30;28060:34;28040:18;;;28033:62;-1:-1:-1;;;28111:18:1;;;28104:52;28173:19;;42562:64:0;27780:418:1;17244:363:0;17323:7;17368:11;:6;17377:2;17368:11;:::i;:::-;17351:6;:13;:28;;17343:62;;;;-1:-1:-1;;;17343:62:0;;28405:2:1;17343:62:0;;;28387:21:1;28444:2;28424:18;;;28417:30;-1:-1:-1;;;28463:18:1;;;28456:51;28524:18;;17343:62:0;28203:345:1;17343:62:0;-1:-1:-1;17497:30:0;17513:4;17497:30;17491:37;-1:-1:-1;;;17487:71:0;;;17244:363::o;18582:314::-;18660:6;18704:10;:6;18713:1;18704:10;:::i;:::-;18687:6;:13;:27;;18679:60;;;;-1:-1:-1;;;18679:60:0;;29819:2:1;18679:60:0;;;29801:21:1;29858:2;29838:18;;;29831:30;-1:-1:-1;;;29877:18:1;;;29870:50;29937:18;;18679:60:0;29617:344:1;18679:60:0;-1:-1:-1;18820:29:0;18836:3;18820:29;18814:36;;18582:314::o;18260:::-;18338:6;18382:10;:6;18391:1;18382:10;:::i;:::-;18365:6;:13;:27;;18357:60;;;;-1:-1:-1;;;18357:60:0;;26861:2:1;18357:60:0;;;26843:21:1;26900:2;26880:18;;;26873:30;-1:-1:-1;;;26919:18:1;;;26912:50;26979:18;;18357:60:0;26659:344:1;18357:60:0;-1:-1:-1;18498:29:0;18514:3;18498:29;18492:36;;18260:314::o;40355:1422::-;40553:15;;40983:17;;;40979:791;;41063:23;:5;41078:7;41063:14;:23::i;:::-;-1:-1:-1;;;;;41053:33:0;;-1:-1:-1;41114:11:0;:7;41124:1;41114:11;:::i;40979:791::-;41161:12;:17;;41177:1;41161:17;41157:613;;;41243:23;:5;41258:7;41243:14;:23::i;:::-;-1:-1:-1;;;;;41233:33:0;;-1:-1:-1;41294:12:0;:7;41304:2;41294:12;:::i;41157:613::-;41330:12;:17;;41346:1;41330:17;41326:444;;;41413:23;:5;41428:7;41413:14;:23::i;:::-;-1:-1:-1;;;;;41403:33:0;;-1:-1:-1;41464:12:0;:7;41474:2;41464:12;:::i;41326:444::-;41500:12;:17;;41516:1;41500:17;41496:274;;;41586:24;:5;41602:7;41586:15;:24::i;:::-;-1:-1:-1;;;;;41576:34:0;;-1:-1:-1;41638:12:0;:7;41648:2;41638:12;:::i;41496:274::-;41697:61;;-1:-1:-1;;;41697:61:0;;31361:2:1;41697:61:0;;;31343:21:1;31400:2;31380:18;;;31373:30;31439:34;31419:18;;;31412:62;-1:-1:-1;;;31490:18:1;;;31483:49;31549:19;;41697:61:0;31159:415:1;80485:1389:0;80765:19;80865:15;80765:19;80891:976;80912:11;:18;80908:1;:22;80891:976;;;80952:26;81023:1;81002:11;:18;:22;;;;:::i;:::-;80997:1;:27;80993:265;;;-1:-1:-1;81066:12:0;80993:265;;;81172:3;81158:8;81167:1;81158:11;;;;;;;;:::i;:::-;;;;;;;81140:15;:29;;;;:::i;:::-;:35;;;;:::i;:::-;81119:56;-1:-1:-1;81209:33:0;81119:56;81209:12;:33;:::i;:::-;81194:48;;80993:265;81308:11;;81334:14;;81286:19;;-1:-1:-1;;;;;81308:11:0;;:25;;81334:11;;81346:1;;81334:14;;;;;;:::i;:::-;;;;;;;81308:41;;;;;;;;;;;;;17601:25:1;;17589:2;17574:18;;17455:177;81308:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81486:11;;:45;;-1:-1:-1;;;81486:45:0;;;;;17601:25:1;;;81286:63:0;;-1:-1:-1;81383:28:0;;;;-1:-1:-1;;;;;81486:11:0;;:32;;17574:18:1;;81486:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;81486:45:0;;;;;;;;;;;;:::i;:::-;81364:167;;;;81601:240;81640:4;81667:18;81708:5;81736:9;81768:19;81810:12;81601:16;:240::i;:::-;81570:271;;:11;:271;:::i;:::-;81556:285;;80937:930;;;;80932:3;;;;;:::i;:::-;;;;80891:976;;;;80801:1073;80485:1389;;;;;;;;:::o;88940:474::-;-1:-1:-1;;;;;;;;;;;;;;;;89082:21:0;;;89078:277;;;89121:12;89147:10;-1:-1:-1;;;;;89139:24:0;89171:4;89139:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89120:60;;;89232:7;89224:49;;;;-1:-1:-1;;;89224:49:0;;28755:2:1;89224:49:0;;;28737:21:1;28794:2;28774:18;;;28767:30;28833:31;28813:18;;;28806:59;28882:18;;89224:49:0;28553:353:1;89224:49:0;89105:180;89078:277;;;89306:37;-1:-1:-1;;;;;89306:19:0;;89326:10;89338:4;89306:19;:37::i;:::-;89389:10;-1:-1:-1;;;;;89370:36:0;89381:6;-1:-1:-1;;;;;89370:36:0;;89401:4;89370:36;;;;17601:25:1;;17589:2;17574:18;;17455:177;89370:36:0;;;;;;;;88940:474;;;:::o;62053:716::-;62477:23;62503:69;62531:4;62503:69;;;;;;;;;;;;;;;;;62511:5;-1:-1:-1;;;;;62503:27:0;;;:69;;;;;:::i;:::-;62587:17;;62477:95;;-1:-1:-1;62587:21:0;62583:179;;62684:10;62673:30;;;;;;;;;;;;:::i;:::-;62665:85;;;;-1:-1:-1;;;62665:85:0;;30168:2:1;62665:85:0;;;30150:21:1;30207:2;30187:18;;;30180:30;30246:34;30226:18;;;30219:62;-1:-1:-1;;;30297:18:1;;;30290:40;30347:19;;62665:85:0;29966:406:1;72801:1413:0;73217:17;;73175:10;;73081:19;;;;;73245:962;73266:10;73262:1;:14;73245:962;;;73304:6;;:43;;73320:20;73341:5;73345:1;73341;:5;:::i;:::-;73320:27;;;;;;;;:::i;:::-;;;;;;;73304:43;;;73313:4;73304:43;73298:49;-1:-1:-1;73374:14:0;73387:1;73374:10;:14;:::i;:::-;73369:1;:19;:53;;73399:20;73420:1;73399:23;;;;;;;;:::i;:::-;;;;;;;73369:53;;;73391:5;73369:53;73362:60;;73451:18;73472:10;73483:1;73472:13;;;;;;;;:::i;:::-;;;;;;;73451:34;;73500:19;73522:1;73527;73522:6;:66;;73546:42;73522:66;;;73531:12;73522:66;73500:88;-1:-1:-1;73603:17:0;73712:14;73725:1;73712:10;:14;:::i;:::-;73707:1;:19;73703:384;;;-1:-1:-1;73767:4:0;73703:384;;;73848:9;;73813:32;;-1:-1:-1;;;;;73848:9:0;:23;73872:10;73883:5;:1;73848:9;73883:5;:::i;:::-;73872:17;;;;;;;;:::i;:::-;;;;;;;73848:42;;;;;;;;;;;;;17601:25:1;;17589:2;17574:18;;17455:177;73848:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;73848:42:0;;;;;;;;;;;;:::i;:::-;:48;;;;-1:-1:-1;73915:15:0;73942:14;73955:1;73942:10;:14;:::i;:::-;73933:5;:1;73937;73933:5;:::i;:::-;:23;:61;;73967:20;73988:5;:1;73992;73988:5;:::i;:::-;73967:27;;;;;;;;:::i;:::-;;;;;;;73933:61;;;73959:5;73933:61;74025:46;;-1:-1:-1;;;74025:46:0;;73915:79;;-1:-1:-1;;;;;;74025:30:0;;;;;:46;;74056:4;;73915:79;;74025:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74013:58;;73794:293;;73703:384;74117:78;74136:10;74148:3;74153:11;74166:4;74172:11;74185:9;74117:18;:78::i;:::-;74103:92;;73283:924;;;73278:3;;;;;:::i;:::-;;;;73245:962;;;;73107:1107;;;72801:1413;;;;;;;;:::o;19553:315::-;19631:6;19675:11;:6;19684:2;19675:11;:::i;:::-;19658:6;:13;:28;;19650:61;;;;-1:-1:-1;;;19650:61:0;;22274:2:1;19650:61:0;;;22256:21:1;22313:2;22293:18;;;22286:30;-1:-1:-1;;;22332:18:1;;;22325:50;22392:18;;19650:61:0;22072:344:1;19650:61:0;-1:-1:-1;19792:29:0;19808:3;19792:29;19786:36;;19553:315::o;18904:314::-;18982:6;19026:10;:6;19035:1;19026:10;:::i;:::-;19009:6;:13;:27;;19001:60;;;;-1:-1:-1;;;19001:60:0;;24216:2:1;19001:60:0;;;24198:21:1;24255:2;24235:18;;;24228:30;-1:-1:-1;;;24274:18:1;;;24267:50;24334:18;;19001:60:0;24014:344:1;19001:60:0;-1:-1:-1;19142:29:0;19158:3;19142:29;19136:36;;18904:314::o;19230:315::-;19308:6;19352:11;:6;19361:2;19352:11;:::i;:::-;19335:6;:13;:28;;19327:61;;;;-1:-1:-1;;;19327:61:0;;24972:2:1;19327:61:0;;;24954:21:1;25011:2;24991:18;;;24984:30;-1:-1:-1;;;25030:18:1;;;25023:50;25090:18;;19327:61:0;24770:344:1;19327:61:0;-1:-1:-1;19469:29:0;19485:3;19469:29;19463:36;;19230:315::o;19880:319::-;19959:7;20004:11;:6;20013:2;20004:11;:::i;:::-;19987:6;:13;:28;;19979:62;;;;-1:-1:-1;;;19979:62:0;;25743:2:1;19979:62:0;;;25725:21:1;25782:2;25762:18;;;25755:30;-1:-1:-1;;;25801:18:1;;;25794:51;25862:18;;19979:62:0;25541:345:1;19979:62:0;-1:-1:-1;20123:29:0;20139:3;20123:29;20117:36;;19880:319::o;51600:229::-;51737:12;51769:52;51791:6;51799:4;51805:1;51808:12;51769:21;:52::i;:::-;51762:59;;51600:229;;;;;;:::o;71818:971::-;72143:9;;:42;;-1:-1:-1;;;72143:42:0;;;;;17601:25:1;;;72052:7:0;;;;-1:-1:-1;;;;;72143:9:0;;;;:23;;17574:18:1;;72143:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;72143:42:0;;;;;;;;;;;;:::i;:::-;:48;;;72108:83;;72242:22;72267:12;-1:-1:-1;;;;;72267:30:0;;72298:3;72303:4;72267:41;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72242:66;-1:-1:-1;;;;;;72323:28:0;;72346:4;72323:28;72319:260;;;72368:43;-1:-1:-1;;;;;72368:16:0;;72385:14;72401:9;72368:16;:43::i;:::-;72319:260;;;-1:-1:-1;;;;;72433:57:0;;;72429:150;;72507:60;-1:-1:-1;;;;;72507:20:0;;72528:11;72541:14;72557:9;72507:20;:60::i;:::-;72639:114;;-1:-1:-1;;;72639:114:0;;-1:-1:-1;;;;;18293:15:1;;;72639:114:0;;;18275:34:1;18345:15;;;18325:18;;;18318:43;18377:18;;;18370:34;;;18440:15;;;18420:18;;;18413:43;72618:18:0;;72639;;;;;;18209:19:1;;72639:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;52720:511::-;52890:12;52948:5;52923:21;:30;;52915:81;;;;-1:-1:-1;;;52915:81:0;;24565:2:1;52915:81:0;;;24547:21:1;24604:2;24584:18;;;24577:30;24643:34;24623:18;;;24616:62;-1:-1:-1;;;24694:18:1;;;24687:36;24740:19;;52915:81:0;24363:402:1;52915:81:0;49117:20;;53007:60;;;;-1:-1:-1;;;53007:60:0;;29113:2:1;53007:60:0;;;29095:21:1;29152:2;29132:18;;;29125:30;29191:31;29171:18;;;29164:59;29240:18;;53007:60:0;28911:353:1;53007:60:0;53081:12;53095:23;53122:6;-1:-1:-1;;;;;53122:11:0;53141:5;53148:4;53122:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53080:73;;;;53171:52;53189:7;53198:10;53210:12;55339;55368:7;55364:530;;;-1:-1:-1;55399:10:0;55392:17;;55364:530;55513:17;;:21;55509:374;;55711:10;55705:17;55772:15;55759:10;55755:2;55751:19;55744:44;55509:374;55854:12;55847:20;;-1:-1:-1;;;55847:20:0;;;;;;;;:::i;14:134:1:-;82:20;;111:31;82:20;111:31;:::i;:::-;14:134;;;:::o;153:761::-;226:5;279:3;272:4;264:6;260:17;256:27;246:55;;297:1;294;287:12;246:55;326:6;320:13;352:4;376:68;392:51;440:2;392:51;:::i;:::-;376:68;:::i;:::-;466:3;490:2;485:3;478:15;518:2;513:3;509:12;502:19;;553:2;545:6;541:15;605:3;600:2;594;591:1;587:10;579:6;575:23;571:32;568:41;565:61;;;622:1;619;612:12;565:61;644:1;654:231;668:2;665:1;662:9;654:231;;;732:3;726:10;749:31;774:5;749:31;:::i;:::-;793:18;;831:12;;;;863;;;;686:1;679:9;654:231;;;-1:-1:-1;903:5:1;;153:761;-1:-1:-1;;;;;;;153:761:1:o;919:681::-;973:5;1026:3;1019:4;1011:6;1007:17;1003:27;993:55;;1044:1;1041;1034:12;993:55;1080:6;1067:20;1106:4;1130:68;1146:51;1194:2;1146:51;:::i;1130:68::-;1220:3;1244:2;1239:3;1232:15;1272:2;1267:3;1263:12;1256:19;;1307:2;1299:6;1295:15;1359:3;1354:2;1348;1345:1;1341:10;1333:6;1329:23;1325:32;1322:41;1319:61;;;1376:1;1373;1366:12;1319:61;1398:1;1408:163;1422:2;1419:1;1416:9;1408:163;;;1479:17;;1467:30;;1517:12;;;;1549;;;;1440:1;1433:9;1408:163;;1605:164;1681:13;;1730;;1723:21;1713:32;;1703:60;;1759:1;1756;1749:12;1774:462;1816:5;1869:3;1862:4;1854:6;1850:17;1846:27;1836:55;;1887:1;1884;1877:12;1836:55;1923:6;1910:20;1954:48;1970:31;1998:2;1970:31;:::i;1954:48::-;2027:2;2018:7;2011:19;2073:3;2066:4;2061:2;2053:6;2049:15;2045:26;2042:35;2039:55;;;2090:1;2087;2080:12;2039:55;2155:2;2148:4;2140:6;2136:17;2129:4;2120:7;2116:18;2103:55;2203:1;2178:16;;;2196:4;2174:27;2167:38;;;;2182:7;1774:462;-1:-1:-1;;;1774:462:1:o;2241:159::-;2341:13;;2363:31;2341:13;2363:31;:::i;2405:247::-;2464:6;2517:2;2505:9;2496:7;2492:23;2488:32;2485:52;;;2533:1;2530;2523:12;2485:52;2572:9;2559:23;2591:31;2616:5;2591:31;:::i;2657:251::-;2727:6;2780:2;2768:9;2759:7;2755:23;2751:32;2748:52;;;2796:1;2793;2786:12;2748:52;2828:9;2822:16;2847:31;2872:5;2847:31;:::i;2913:1176::-;3057:6;3065;3118:2;3106:9;3097:7;3093:23;3089:32;3086:52;;;3134:1;3131;3124:12;3086:52;3161:16;;-1:-1:-1;;;;;3226:14:1;;;3223:34;;;3253:1;3250;3243:12;3223:34;3291:6;3280:9;3276:22;3266:32;;3336:7;3329:4;3325:2;3321:13;3317:27;3307:55;;3358:1;3355;3348:12;3307:55;3387:2;3381:9;3409:4;3433:68;3449:51;3497:2;3449:51;:::i;3433:68::-;3523:3;3547:2;3542:3;3535:15;3575:2;3570:3;3566:12;3559:19;;3606:2;3602;3598:11;3654:7;3649:2;3643;3640:1;3636:10;3632:2;3628:19;3624:28;3621:41;3618:61;;;3675:1;3672;3665:12;3618:61;3697:1;3688:10;;3707:156;3721:2;3718:1;3715:9;3707:156;;;3778:10;;3766:23;;3739:1;3732:9;;;;;3809:12;;;;3841;;3707:156;;;-1:-1:-1;3918:18:1;;;3912:25;3882:5;;-1:-1:-1;3912:25:1;;-1:-1:-1;;;3949:16:1;;;3946:36;;;3978:1;3975;3968:12;3946:36;;4001:82;4075:7;4064:8;4053:9;4049:24;4001:82;:::i;:::-;3991:92;;;2913:1176;;;;;:::o;4094:1182::-;4287:6;4295;4303;4311;4319;4327;4335;4388:3;4376:9;4367:7;4363:23;4359:33;4356:53;;;4405:1;4402;4395:12;4356:53;4432:23;;-1:-1:-1;;;;;4504:14:1;;;4501:34;;;4531:1;4528;4521:12;4501:34;4554:61;4607:7;4598:6;4587:9;4583:22;4554:61;:::i;:::-;4544:71;;4668:2;4657:9;4653:18;4640:32;4624:48;;4697:2;4687:8;4684:16;4681:36;;;4713:1;4710;4703:12;4681:36;;4736:63;4791:7;4780:8;4769:9;4765:24;4736:63;:::i;:::-;4726:73;;;4849:2;4838:9;4834:18;4821:32;4862:31;4887:5;4862:31;:::i;:::-;4912:5;-1:-1:-1;4964:2:1;4949:18;;4936:32;;-1:-1:-1;5020:3:1;5005:19;;4992:33;5034;4992;5034;:::i;:::-;5086:7;-1:-1:-1;5140:3:1;5125:19;;5112:33;;-1:-1:-1;5197:3:1;5182:19;;5169:33;5211;5169;5211;:::i;:::-;5263:7;5253:17;;;4094:1182;;;;;;;;;;:::o;5281:202::-;5348:6;5401:2;5389:9;5380:7;5376:23;5372:32;5369:52;;;5417:1;5414;5407:12;5369:52;5440:37;5467:9;5440:37;:::i;5488:180::-;5547:6;5600:2;5588:9;5579:7;5575:23;5571:32;5568:52;;;5616:1;5613;5606:12;5568:52;-1:-1:-1;5639:23:1;;5488:180;-1:-1:-1;5488:180:1:o;5673:184::-;5743:6;5796:2;5784:9;5775:7;5771:23;5767:32;5764:52;;;5812:1;5809;5802:12;5764:52;-1:-1:-1;5835:16:1;;5673:184;-1:-1:-1;5673:184:1:o;5862:320::-;5930:6;5983:2;5971:9;5962:7;5958:23;5954:32;5951:52;;;5999:1;5996;5989:12;5951:52;6026:23;;-1:-1:-1;;;;;6061:30:1;;6058:50;;;6104:1;6101;6094:12;6058:50;6127:49;6168:7;6159:6;6148:9;6144:22;6127:49;:::i;:::-;6117:59;5862:320;-1:-1:-1;;;;5862:320:1:o;6187:388::-;6264:6;6272;6325:2;6313:9;6304:7;6300:23;6296:32;6293:52;;;6341:1;6338;6331:12;6293:52;6368:23;;-1:-1:-1;;;;;6403:30:1;;6400:50;;;6446:1;6443;6436:12;6400:50;6469:49;6510:7;6501:6;6490:9;6486:22;6469:49;:::i;:::-;6459:59;6565:2;6550:18;;;;6537:32;;-1:-1:-1;;;;6187:388:1:o;6580:330::-;6663:6;6671;6724:2;6712:9;6703:7;6699:23;6695:32;6692:52;;;6740:1;6737;6730:12;6692:52;6779:9;6766:23;6798:31;6823:5;6798:31;:::i;:::-;6848:5;6900:2;6885:18;;;;6872:32;;-1:-1:-1;;;6580:330:1:o;6915:1773::-;7123:6;7131;7139;7147;7155;7163;7171;7224:3;7212:9;7203:7;7199:23;7195:33;7192:53;;;7241:1;7238;7231:12;7192:53;7280:9;7267:23;7299:31;7324:5;7299:31;:::i;:::-;7349:5;-1:-1:-1;7373:2:1;7407:18;;;7394:32;;-1:-1:-1;7478:2:1;7463:18;;7450:32;7491:33;7450:32;7491:33;:::i;:::-;7543:7;-1:-1:-1;7597:2:1;7582:18;;7569:32;;-1:-1:-1;7652:3:1;7637:19;;7624:33;-1:-1:-1;;;;;7706:14:1;;;7703:34;;;7733:1;7730;7723:12;7703:34;7756:61;7809:7;7800:6;7789:9;7785:22;7756:61;:::i;:::-;7746:71;;7870:3;7859:9;7855:19;7842:33;7826:49;;7900:2;7890:8;7887:16;7884:36;;;7916:1;7913;7906:12;7884:36;-1:-1:-1;7939:24:1;;7994:4;7986:13;;7982:27;-1:-1:-1;7972:55:1;;8023:1;8020;8013:12;7972:55;8059:2;8046:16;8082:68;8098:51;8146:2;8098:51;:::i;8082:68::-;8172:3;8196:2;8191:3;8184:15;8224:2;8219:3;8215:12;8208:19;;8255:2;8251;8247:11;8303:7;8298:2;8292;8289:1;8285:10;8281:2;8277:19;8273:28;8270:41;8267:61;;;8324:1;8321;8314:12;8267:61;8346:1;8337:10;;8356:244;8370:2;8367:1;8364:9;8356:244;;;8443:3;8430:17;8460:33;8485:7;8460:33;:::i;:::-;8506:20;;8388:1;8381:9;;;;;8546:12;;;;8578;;8356:244;;;8360:3;8619:5;8609:15;;;;;;;8643:39;8677:3;8666:9;8662:19;8643:39;:::i;:::-;8633:49;;6915:1773;;;;;;;;;;:::o;8693:766::-;8827:6;8835;8843;8851;8859;8867;8920:3;8908:9;8899:7;8895:23;8891:33;8888:53;;;8937:1;8934;8927:12;8888:53;8976:9;8963:23;8995:31;9020:5;8995:31;:::i;:::-;9045:5;-1:-1:-1;9097:2:1;9082:18;;9069:32;;-1:-1:-1;9153:2:1;9138:18;;9125:32;9166:33;9125:32;9166:33;:::i;:::-;9218:7;-1:-1:-1;9272:2:1;9257:18;;9244:32;;-1:-1:-1;9323:3:1;9308:19;;9295:33;;-1:-1:-1;9380:3:1;9365:19;;9352:33;9394;9352;9394;:::i;:::-;9446:7;9436:17;;;8693:766;;;;;;;;:::o;10297:1102::-;10390:6;10421:2;10464;10452:9;10443:7;10439:23;10435:32;10432:52;;;10480:1;10477;10470:12;10432:52;10507:16;;-1:-1:-1;;;;;10572:14:1;;;10569:34;;;10599:1;10596;10589:12;10569:34;10622:22;;;;10678:4;10660:16;;;10656:27;10653:47;;;10696:1;10693;10686:12;10653:47;10722:22;;:::i;:::-;10775:2;10769:9;10803:2;10793:8;10790:16;10787:36;;;10819:1;10816;10809:12;10787:36;10842:17;;;-1:-1:-1;10890:4:1;10882:13;;10878:27;-1:-1:-1;10868:55:1;;10919:1;10916;10909:12;10868:55;10948:2;10942:9;10973:48;10989:31;11017:2;10989:31;:::i;10973:48::-;11044:2;11037:5;11030:17;11084:7;11079:2;11074;11070;11066:11;11062:20;11059:33;11056:53;;;11105:1;11102;11095:12;11056:53;11118:54;11169:2;11164;11157:5;11153:14;11148:2;11144;11140:11;11118:54;:::i;:::-;11181:20;;-1:-1:-1;11233:39:1;11260:11;;;11233:39;:::i;:::-;11228:2;11221:5;11217:14;11210:63;11305;11364:2;11360;11356:11;11305:63;:::i;:::-;11300:2;11289:14;;11282:87;11293:5;10297:1102;-1:-1:-1;;;;;;10297:1102:1:o;11778:315::-;11846:6;11854;11907:2;11895:9;11886:7;11882:23;11878:32;11875:52;;;11923:1;11920;11913:12;11875:52;11959:9;11946:23;11936:33;;12019:2;12008:9;12004:18;11991:32;12032:31;12057:5;12032:31;:::i;:::-;12082:5;12072:15;;;11778:315;;;;;:::o;12098:312::-;12177:6;12185;12238:2;12226:9;12217:7;12213:23;12209:32;12206:52;;;12254:1;12251;12244:12;12206:52;12283:9;12277:16;12267:26;;12336:2;12325:9;12321:18;12315:25;12349:31;12374:5;12349:31;:::i;12415:469::-;12476:3;12514:5;12508:12;12541:6;12536:3;12529:19;12567:4;12596:2;12591:3;12587:12;12580:19;;12633:2;12626:5;12622:14;12654:1;12664:195;12678:6;12675:1;12672:13;12664:195;;;12743:13;;-1:-1:-1;;;;;12739:39:1;12727:52;;12799:12;;;;12834:15;;;;12775:1;12693:9;12664:195;;;-1:-1:-1;12875:3:1;;12415:469;-1:-1:-1;;;;;12415:469:1:o;12889:435::-;12942:3;12980:5;12974:12;13007:6;13002:3;12995:19;13033:4;13062:2;13057:3;13053:12;13046:19;;13099:2;13092:5;13088:14;13120:1;13130:169;13144:6;13141:1;13138:13;13130:169;;;13205:13;;13193:26;;13239:12;;;;13274:15;;;;13166:1;13159:9;13130:169;;13516:274;13645:3;13683:6;13677:13;13699:53;13745:6;13740:3;13733:4;13725:6;13721:17;13699:53;:::i;:::-;13768:16;;;;;13516:274;-1:-1:-1;;13516:274:1:o;14005:203::-;-1:-1:-1;;;;;14169:32:1;;;;14151:51;;14139:2;14124:18;;14005:203::o;15054:519::-;-1:-1:-1;;;;;15369:15:1;;;15351:34;;15421:15;;;;15416:2;15401:18;;15394:43;15468:2;15453:18;;15446:34;;;;15511:2;15496:18;;15489:34;15554:3;15539:19;;15532:35;;;;15300:3;15285:19;;15054:519::o;15857:488::-;16129:2;16118:9;16111:21;16092:4;16155:56;16207:2;16196:9;16192:18;16184:6;16155:56;:::i;:::-;16259:9;16251:6;16247:22;16242:2;16231:9;16227:18;16220:50;16287:52;16332:6;16324;16287:52;:::i;:::-;16279:60;15857:488;-1:-1:-1;;;;;15857:488:1:o;16350:559::-;16650:2;16639:9;16632:21;16613:4;16676:56;16728:2;16717:9;16713:18;16705:6;16676:56;:::i;:::-;16780:9;16772:6;16768:22;16763:2;16752:9;16748:18;16741:50;16808:52;16853:6;16845;16808:52;:::i;:::-;16800:60;;;16896:6;16891:2;16880:9;16876:18;16869:34;16350:559;;;;;;:::o;16914:536::-;17199:2;17188:9;17181:21;17162:4;17225:56;17277:2;17266:9;17262:18;17254:6;17225:56;:::i;:::-;17329:9;17321:6;17317:22;17312:2;17301:9;17297:18;17290:50;17357:44;17394:6;17386;17357:44;:::i;17637:334::-;-1:-1:-1;;;;;17897:15:1;;;17879:34;;17949:15;;17944:2;17929:18;;17922:43;17829:2;17814:18;;17637:334::o;20448:383::-;20597:2;20586:9;20579:21;20560:4;20629:6;20623:13;20672:6;20667:2;20656:9;20652:18;20645:34;20688:66;20747:6;20742:2;20731:9;20727:18;20722:2;20714:6;20710:15;20688:66;:::i;:::-;20815:2;20794:15;-1:-1:-1;;20790:29:1;20775:45;;;;20822:2;20771:54;;20448:383;-1:-1:-1;;20448:383:1:o;20836:406::-;21038:2;21020:21;;;21077:2;21057:18;;;21050:30;21116:34;21111:2;21096:18;;21089:62;-1:-1:-1;;;21182:2:1;21167:18;;21160:40;21232:3;21217:19;;20836:406::o;21655:412::-;21857:2;21839:21;;;21896:2;21876:18;;;21869:30;21935:34;21930:2;21915:18;;21908:62;-1:-1:-1;;;22001:2:1;21986:18;;21979:46;22057:3;22042:19;;21655:412::o;25891:413::-;26093:2;26075:21;;;26132:2;26112:18;;;26105:30;26171:34;26166:2;26151:18;;26144:62;-1:-1:-1;;;26237:2:1;26222:18;;26215:47;26294:3;26279:19;;25891:413::o;27008:406::-;27210:2;27192:21;;;27249:2;27229:18;;;27222:30;27288:34;27283:2;27268:18;;27261:62;-1:-1:-1;;;27354:2:1;27339:18;;27332:40;27404:3;27389:19;;27008:406::o;27419:356::-;27621:2;27603:21;;;27640:18;;;27633:30;27699:34;27694:2;27679:18;;27672:62;27766:2;27751:18;;27419:356::o;30377:417::-;30579:2;30561:21;;;30618:2;30598:18;;;30591:30;30657:34;30652:2;30637:18;;30630:62;-1:-1:-1;;;30723:2:1;30708:18;;30701:51;30784:3;30769:19;;30377:417::o;30799:355::-;31001:2;30983:21;;;31040:2;31020:18;;;31013:30;31079:33;31074:2;31059:18;;31052:61;31145:2;31130:18;;30799:355::o;31957:509::-;32204:25;;;32260:2;32245:18;;32238:34;;;;-1:-1:-1;;;;;32308:32:1;;;;32303:2;32288:18;;32281:60;32384:14;32377:22;32372:2;32357:18;;32350:50;32444:14;32437:22;32431:3;32416:19;;32409:51;32191:3;32176:19;;31957:509::o;33389:253::-;33461:2;33455:9;33503:4;33491:17;;-1:-1:-1;;;;;33523:34:1;;33559:22;;;33520:62;33517:88;;;33585:18;;:::i;:::-;33621:2;33614:22;33389:253;:::o;33647:275::-;33718:2;33712:9;33783:2;33764:13;;-1:-1:-1;;33760:27:1;33748:40;;-1:-1:-1;;;;;33803:34:1;;33839:22;;;33800:62;33797:88;;;33865:18;;:::i;:::-;33901:2;33894:22;33647:275;;-1:-1:-1;33647:275:1:o;33927:191::-;33995:4;-1:-1:-1;;;;;34017:30:1;;34014:56;;;34050:18;;:::i;:::-;-1:-1:-1;34095:1:1;34091:14;34107:4;34087:25;;33927:191::o;34123:186::-;34171:4;-1:-1:-1;;;;;34193:30:1;;34190:56;;;34226:18;;:::i;:::-;-1:-1:-1;34292:2:1;34271:15;-1:-1:-1;;34267:29:1;34298:4;34263:40;;34123:186::o;34314:128::-;34354:3;34385:1;34381:6;34378:1;34375:13;34372:39;;;34391:18;;:::i;:::-;-1:-1:-1;34427:9:1;;34314:128::o;34447:217::-;34487:1;34513;34503:132;;34557:10;34552:3;34548:20;34545:1;34538:31;34592:4;34589:1;34582:15;34620:4;34617:1;34610:15;34503:132;-1:-1:-1;34649:9:1;;34447:217::o;34669:168::-;34709:7;34775:1;34771;34767:6;34763:14;34760:1;34757:21;34752:1;34745:9;34738:17;34734:45;34731:71;;;34782:18;;:::i;:::-;-1:-1:-1;34822:9:1;;34669:168::o;34842:125::-;34882:4;34910:1;34907;34904:8;34901:34;;;34915:18;;:::i;:::-;-1:-1:-1;34952:9:1;;34842:125::o;34972:258::-;35044:1;35054:113;35068:6;35065:1;35062:13;35054:113;;;35144:11;;;35138:18;35125:11;;;35118:39;35090:2;35083:10;35054:113;;;35185:6;35182:1;35179:13;35176:48;;;-1:-1:-1;;35220:1:1;35202:16;;35195:27;34972:258::o;35235:135::-;35274:3;-1:-1:-1;;35295:17:1;;35292:43;;;35315:18;;:::i;:::-;-1:-1:-1;35362:1:1;35351:13;;35235:135::o;35375:127::-;35436:10;35431:3;35427:20;35424:1;35417:31;35467:4;35464:1;35457:15;35491:4;35488:1;35481:15;35507:127;35568:10;35563:3;35559:20;35556:1;35549:31;35599:4;35596:1;35589:15;35623:4;35620:1;35613:15;35639:127;35700:10;35695:3;35691:20;35688:1;35681:31;35731:4;35728:1;35721:15;35755:4;35752:1;35745:15;35771:131;-1:-1:-1;;;;;35846:31:1;;35836:42;;35826:70;;35892:1;35889;35882:12
Swarm Source
ipfs://3fe43e9d5767501c95f9d4f08d2775fa221c770fb1d3221f7d124546bb927e64
OVERVIEW
AI swap with lowest gas fees on multi-chainsNet Worth in USD
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.