Feature Tip: Add private address tag to any address under My Name Tag !
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| 0xbc9c6a7b18a327f3f2a75f04e348011cdb66f303bca5ae9c472be05dc675398b | Start Execution | (pending) | 4 days ago | IN | 0.01 ETH | (Pending) | |||
| Start Execution | 22947067 | 110 days ago | IN | 0 ETH | 0.00230732 | ||||
| Start Execution | 22944999 | 111 days ago | IN | 0 ETH | 0.00156798 | ||||
| Start Execution | 22939214 | 111 days ago | IN | 0 ETH | 0.00147515 | ||||
| Start Execution | 22931183 | 113 days ago | IN | 0 ETH | 0.0021081 | ||||
| Start Execution | 22930502 | 113 days ago | IN | 0 ETH | 0.0006401 | ||||
| Start Execution | 22921288 | 114 days ago | IN | 0 ETH | 0.00021374 | ||||
| Start Execution | 22915814 | 115 days ago | IN | 0 ETH | 0.00029127 | ||||
| Start Execution | 22914013 | 115 days ago | IN | 0 ETH | 0.00016314 | ||||
| Start Execution | 22911249 | 115 days ago | IN | 0 ETH | 0.00051303 | ||||
| Start Execution | 22909165 | 116 days ago | IN | 0 ETH | 0.00014133 | ||||
| Start Execution | 22909146 | 116 days ago | IN | 0 ETH | 0.00009881 | ||||
| Start Execution | 22898069 | 117 days ago | IN | 0 ETH | 0.00061236 | ||||
| Start Execution | 22894457 | 118 days ago | IN | 0 ETH | 0.00172752 | ||||
| Start Execution | 22887518 | 119 days ago | IN | 0 ETH | 0.00010774 | ||||
| Start Execution | 22882587 | 119 days ago | IN | 0 ETH | 0.00161205 | ||||
| Start Execution | 22881241 | 120 days ago | IN | 0 ETH | 0.00128386 | ||||
| Start Execution | 22873955 | 121 days ago | IN | 0 ETH | 0.00041477 | ||||
| Start Execution | 22872961 | 121 days ago | IN | 0 ETH | 0.00013959 | ||||
| Start Execution | 22872930 | 121 days ago | IN | 0 ETH | 0.00017962 | ||||
| Start Execution | 22866938 | 122 days ago | IN | 0 ETH | 0.00020123 | ||||
| Start Execution | 22854556 | 123 days ago | IN | 0 ETH | 0.00006149 | ||||
| Start Execution | 22854550 | 123 days ago | IN | 0 ETH | 0.00006992 | ||||
| Start Execution | 22853167 | 123 days ago | IN | 0 ETH | 0.00008735 | ||||
| Start Execution | 22853154 | 123 days ago | IN | 0 ETH | 0.00008897 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 22809841 | 129 days ago | 0.045 ETH | ||||
| Transfer | 22018531 | 240 days ago | 0.7 ETH | ||||
| Transfer | 21943486 | 251 days ago | 0.3 ETH | ||||
| Transfer | 21793675 | 272 days ago | 0.01 ETH | ||||
| Transfer | 21793666 | 272 days ago | 0.017 ETH | ||||
| Transfer | 21349696 | 334 days ago | 0.105 ETH | ||||
| Transfer | 21182721 | 357 days ago | 0.012 ETH | ||||
| Transfer | 20646892 | 432 days ago | 0.009 ETH | ||||
| Transfer | 20633324 | 434 days ago | 0.003 ETH | ||||
| Transfer | 20539664 | 447 days ago | 0.002 ETH | ||||
| Transfer | 20452687 | 459 days ago | 0.00375 ETH | ||||
| Transfer | 20451915 | 459 days ago | 0.005 ETH | ||||
| Transfer | 20451862 | 459 days ago | 0.0008 ETH | ||||
| Transfer | 20409142 | 465 days ago | 0.005 ETH | ||||
| Transfer | 20408882 | 465 days ago | 0.00267 ETH | ||||
| Transfer | 20408564 | 465 days ago | 0.0008 ETH | ||||
| Transfer | 20408542 | 465 days ago | 0.01 ETH | ||||
| Transfer | 20408488 | 465 days ago | 0.002 ETH | ||||
| Transfer | 20408264 | 465 days ago | 0.005 ETH | ||||
| Transfer | 20395711 | 467 days ago | 0.008 ETH | ||||
| Transfer | 20295447 | 481 days ago | 0.011 ETH | ||||
| Transfer | 20242543 | 488 days ago | 1 ETH | ||||
| Transfer | 19908843 | 535 days ago | 0.01 ETH | ||||
| Transfer | 19840849 | 544 days ago | 0.01 ETH | ||||
| Transfer | 19634127 | 573 days ago | 0.26 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Router
Compiler Version
v0.6.11+commit.5ef660b1
Contract Source Code (Solidity Standard Json-Input format)
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
import {
TransactionData,
Action,
TokenAmount,
Fee,
AbsoluteTokenAmount,
AmountType
} from "../shared/Structs.sol";
import { ERC20 } from "../shared/ERC20.sol";
import { SafeERC20 } from "../shared/SafeERC20.sol";
import { SignatureVerifier } from "./SignatureVerifier.sol";
import { Ownable } from "./Ownable.sol";
import { Core } from "./Core.sol";
interface Chi {
function freeUpTo(uint256) external;
}
contract Router is SignatureVerifier("Zerion Router"), Ownable {
using SafeERC20 for ERC20;
address internal immutable core_;
address internal constant CHI = 0x0000000000004946c0e9F43F4Dee607b0eF1fA1c;
address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
uint256 internal constant DELIMITER = 1e18; // 100%
uint256 internal constant FEE_LIMIT = 1e16; // 1%
constructor(address payable core) public {
require(core != address(0), "R: empty core");
core_ = core;
}
function returnLostTokens(
address token,
address payable beneficiary
)
external
onlyOwner
{
if (token == ETH) {
(bool success, ) = beneficiary.call{value: address(this).balance}(new bytes(0));
require(success, "R: bad beneficiary");
} else {
ERC20(token).safeTransfer(beneficiary, ERC20(token).balanceOf(address(this)), "R");
}
}
function getRequiredAllowances(
TokenAmount[] calldata inputs,
address account
)
external
view
returns (AbsoluteTokenAmount[] memory)
{
uint256 length = inputs.length;
AbsoluteTokenAmount[] memory requiredAllowances = new AbsoluteTokenAmount[](length);
uint256 required;
uint256 current;
for (uint256 i = 0; i < length; i++) {
required = getAbsoluteAmount(inputs[i], account);
current = ERC20(inputs[i].token).allowance(account, address(this));
requiredAllowances[i] = AbsoluteTokenAmount({
token: inputs[i].token,
amount: required > current ? required - current : 0
});
}
return requiredAllowances;
}
function getRequiredBalances(
TokenAmount[] calldata inputs,
address account
)
external
view
returns (AbsoluteTokenAmount[] memory)
{
uint256 length = inputs.length;
AbsoluteTokenAmount[] memory requiredBalances = new AbsoluteTokenAmount[](length);
uint256 required;
uint256 current;
for (uint256 i = 0; i < length; i++) {
required = getAbsoluteAmount(inputs[i], account);
current = ERC20(inputs[i].token).balanceOf(account);
requiredBalances[i] = AbsoluteTokenAmount({
token: inputs[i].token,
amount: required > current ? required - current : 0
});
}
return requiredBalances;
}
/**
* @return Address of the Core contract used.
*/
function core()
external
view
returns (address)
{
return core_;
}
function startExecution(
TransactionData memory data,
bytes memory signature
)
public
payable
returns (AbsoluteTokenAmount[] memory)
{
address payable account = getAccountFromSignature(data, signature);
updateNonce(account);
return startExecution(
data.actions,
data.inputs,
data.fee,
data.requiredOutputs,
account
);
}
function startExecution(
Action[] memory actions,
TokenAmount[] memory inputs,
Fee memory fee,
AbsoluteTokenAmount[] memory requiredOutputs
)
public
payable
returns (AbsoluteTokenAmount[] memory)
{
return startExecution(
actions,
inputs,
fee,
requiredOutputs,
msg.sender
);
}
function startExecution(
Action[] memory actions,
TokenAmount[] memory inputs,
Fee memory fee,
AbsoluteTokenAmount[] memory requiredOutputs,
address payable account
)
internal
returns (AbsoluteTokenAmount[] memory)
{
// save initial gas to burn gas token later
uint256 gas = gasleft();
// transfer tokens to core_, handle fees (if any), and add these tokens to outputs
transferTokens(inputs, fee, account);
AbsoluteTokenAmount[] memory modifiedOutputs = modifyOutputs(requiredOutputs, inputs);
// call Core contract with all provided ETH, actions, expected outputs and account address
AbsoluteTokenAmount[] memory actualOutputs = Core(payable(core_)).executeActions(
actions,
modifiedOutputs,
account
);
// try to burn gas token to save some gas
uint256 gasSpent = 21000 + gas - gasleft() + 16 * msg.data.length;
Chi(CHI).freeUpTo((gasSpent + 14154) / 41130);
// return tokens that were returned to the account address
return actualOutputs;
}
function transferTokens(
TokenAmount[] memory inputs,
Fee memory fee,
address account
)
internal
{
address token;
uint256 absoluteAmount;
uint256 feeAmount;
uint256 length = inputs.length;
if (fee.share > 0) {
require(fee.beneficiary != address(0), "R: bad beneficiary");
require(fee.share <= FEE_LIMIT, "R: bad fee");
}
for (uint256 i = 0; i < length; i++) {
token = inputs[i].token;
absoluteAmount = getAbsoluteAmount(inputs[i], account);
require(absoluteAmount > 0, "R: zero amount");
feeAmount = mul(absoluteAmount, fee.share) / DELIMITER;
if (feeAmount > 0) {
ERC20(token).safeTransferFrom(
account,
fee.beneficiary,
feeAmount,
"R[1]"
);
}
ERC20(token).safeTransferFrom(
account,
core_,
absoluteAmount - feeAmount,
"R[2]"
);
}
if (msg.value > 0) {
feeAmount = mul(msg.value, fee.share) / DELIMITER;
if (feeAmount > 0) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = fee.beneficiary.call{value: feeAmount}(new bytes(0));
require(success, "ETH transfer to beneficiary failed");
}
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = core_.call{value: msg.value - feeAmount}(new bytes(0));
require(success, "ETH transfer to Core failed");
}
}
function getAbsoluteAmount(
TokenAmount memory tokenAmount,
address account
)
internal
view
returns (uint256)
{
address token = tokenAmount.token;
AmountType amountType = tokenAmount.amountType;
uint256 amount = tokenAmount.amount;
require(
amountType == AmountType.Relative || amountType == AmountType.Absolute,
"R: bad amount type"
);
if (amountType == AmountType.Relative) {
require(amount <= DELIMITER, "R: bad amount");
if (amount == DELIMITER) {
return ERC20(token).balanceOf(account);
} else {
return mul(ERC20(token).balanceOf(account), amount) / DELIMITER;
}
} else {
return amount;
}
}
function modifyOutputs(
AbsoluteTokenAmount[] memory requiredOutputs,
TokenAmount[] memory inputs
)
internal
view
returns (AbsoluteTokenAmount[] memory)
{
uint256 ethInput = msg.value > 0 ? 1 : 0;
AbsoluteTokenAmount[] memory modifiedOutputs = new AbsoluteTokenAmount[](
requiredOutputs.length + inputs.length + ethInput
);
for (uint256 i = 0; i < requiredOutputs.length; i++) {
modifiedOutputs[i] = requiredOutputs[i];
}
for (uint256 i = 0; i < inputs.length; i++) {
modifiedOutputs[requiredOutputs.length + i] = AbsoluteTokenAmount({
token: inputs[i].token,
amount: 0
});
}
if (ethInput > 0) {
modifiedOutputs[requiredOutputs.length + inputs.length] = AbsoluteTokenAmount({
token: ETH,
amount: 0
});
}
return modifiedOutputs;
}
function mul(
uint256 a,
uint256 b
)
internal
pure
returns (uint256)
{
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "R: mul overflow");
return c;
}
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
interface ERC20 {
function approve(address, uint256) external returns (bool);
function transfer(address, uint256) external returns (bool);
function transferFrom(address, address, uint256) external returns (bool);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address) external view returns (uint256);
function allowance(address, address) external view returns (uint256);
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
import "./ERC20.sol";
/**
* @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 ERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
function safeTransfer(
ERC20 token,
address to,
uint256 value,
string memory location
)
internal
{
callOptionalReturn(
token,
abi.encodeWithSelector(
token.transfer.selector,
to,
value
),
"transfer",
location
);
}
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 value,
string memory location
)
internal
{
callOptionalReturn(
token,
abi.encodeWithSelector(
token.transferFrom.selector,
from,
to,
value
),
"transferFrom",
location
);
}
function safeApprove(
ERC20 token,
address spender,
uint256 value,
string memory location
)
internal
{
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: bad approve call"
);
callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
value
),
"approve",
location
);
}
/**
* @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).
* @param location Location of the call (for debug).
*/
function callOptionalReturn(
ERC20 token,
bytes memory data,
string memory functionName,
string memory location
)
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 implement two-steps call as callee is a contract is a responsibility of a caller.
// 1. The call itself is made, and success asserted
// 2. The return value is decoded, which in turn checks the size of the returned data.
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(
success,
string(
abi.encodePacked(
"SafeERC20: ",
functionName,
" failed in ",
location
)
)
);
if (returndata.length > 0) { // Return data is optional
require(
abi.decode(returndata, (bool)),
string(
abi.encodePacked(
"SafeERC20: ",
functionName,
" returned false in ",
location
)
)
);
}
}
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
import { TransactionData, Action, AbsoluteTokenAmount, Fee, TokenAmount } from "../shared/Structs.sol";
contract SignatureVerifier {
mapping (address => uint256) internal nonce_;
bytes32 internal immutable domainSeparator_;
bytes32 internal constant DOMAIN_SEPARATOR_TYPEHASH = keccak256(
abi.encodePacked(
"EIP712Domain(",
"string name,",
"address verifyingContract",
")"
)
);
bytes32 internal constant TX_DATA_TYPEHASH = keccak256(
abi.encodePacked(
TX_DATA_ENCODED_TYPE,
ABSOLUTE_TOKEN_AMOUNT_ENCODED_TYPE,
ACTION_ENCODED_TYPE,
FEE_ENCODED_TYPE,
TOKEN_AMOUNT_ENCODED_TYPE
)
);
bytes32 internal constant ABSOLUTE_TOKEN_AMOUNT_TYPEHASH =
keccak256(ABSOLUTE_TOKEN_AMOUNT_ENCODED_TYPE);
bytes32 internal constant ACTION_TYPEHASH = keccak256(
abi.encodePacked(
ACTION_ENCODED_TYPE,
TOKEN_AMOUNT_ENCODED_TYPE
)
);
bytes32 internal constant FEE_TYPEHASH = keccak256(FEE_ENCODED_TYPE);
bytes32 internal constant TOKEN_AMOUNT_TYPEHASH = keccak256(TOKEN_AMOUNT_ENCODED_TYPE);
bytes internal constant TX_DATA_ENCODED_TYPE = abi.encodePacked(
"TransactionData(",
"Action[] actions,",
"TokenAmount[] inputs,",
"Fee fee,",
"AbsoluteTokenAmount[] requiredOutputs,",
"uint256 nonce",
")"
);
bytes internal constant ABSOLUTE_TOKEN_AMOUNT_ENCODED_TYPE = abi.encodePacked(
"AbsoluteTokenAmount(",
"address token,",
"uint256 amount",
")"
);
bytes internal constant ACTION_ENCODED_TYPE = abi.encodePacked(
"Action(",
"bytes32 protocolAdapterName,",
"uint8 actionType,",
"TokenAmount[] tokenAmounts,",
"bytes data",
")"
);
bytes internal constant FEE_ENCODED_TYPE = abi.encodePacked(
"Fee(",
"uint256 share,",
"address beneficiary",
")"
);
bytes internal constant TOKEN_AMOUNT_ENCODED_TYPE = abi.encodePacked(
"TokenAmount(",
"address token,",
"uint256 amount,",
"uint8 amountType",
")"
);
constructor(string memory name) public {
domainSeparator_ = keccak256(
abi.encode(
DOMAIN_SEPARATOR_TYPEHASH,
keccak256(abi.encodePacked(name)),
address(this)
)
);
}
/**
* @return Address of the Core contract used.
*/
function nonce(
address account
)
external
view
returns (uint256)
{
return nonce_[account];
}
function updateNonce(
address account
)
internal
{
nonce_[account]++;
}
function getAccountFromSignature(
TransactionData memory data,
bytes memory signature
)
public
view
returns (address payable)
{
(uint8 v, bytes32 r, bytes32 s) = splitSignature(signature);
bytes32 hashedData = keccak256(
abi.encodePacked(
bytes1(0x19),
bytes1(0x01),
domainSeparator_,
hash(data)
)
);
address signer = ecrecover(hashedData, v, r, s);
require(signer != address(0), "SV: bad signature");
require(nonce_[signer] == data.nonce, "SV: bad nonce");
return payable(signer);
}
/// @return Hash to be signed by tokens supplier.
function hash(
TransactionData memory data
)
internal
pure
returns (bytes32)
{
return keccak256(
abi.encode(
TX_DATA_TYPEHASH,
hash(data.actions),
hash(data.inputs),
hash(data.fee),
hash(data.requiredOutputs),
data.nonce
)
);
}
function hash(
Action[] memory actions
)
internal
pure
returns (bytes32)
{
bytes memory actionsData = new bytes(0);
uint256 length = actions.length;
for (uint256 i = 0; i < length; i++) {
actionsData = abi.encodePacked(
actionsData,
keccak256(
abi.encode(
ACTION_TYPEHASH,
actions[i].protocolAdapterName,
actions[i].actionType,
hash(actions[i].tokenAmounts),
keccak256(actions[i].data)
)
)
);
}
return keccak256(actionsData);
}
function hash(
TokenAmount[] memory tokenAmounts
)
internal
pure
returns (bytes32)
{
bytes memory tokenAmountsData = new bytes(0);
uint256 length = tokenAmounts.length;
for (uint256 i = 0; i < length; i++) {
tokenAmountsData = abi.encodePacked(
tokenAmountsData,
keccak256(
abi.encode(
TOKEN_AMOUNT_TYPEHASH,
tokenAmounts[i].token,
tokenAmounts[i].amount,
tokenAmounts[i].amountType
)
)
);
}
return keccak256(tokenAmountsData);
}
function hash(
Fee memory fee
)
internal
pure
returns (bytes32)
{
return keccak256(
abi.encode(
FEE_TYPEHASH,
fee.share,
fee.beneficiary
)
);
}
function hash(
AbsoluteTokenAmount[] memory absoluteTokenAmounts
)
internal
pure
returns (bytes32)
{
bytes memory absoluteTokenAmountsData = new bytes(0);
uint256 length = absoluteTokenAmounts.length;
for (uint256 i = 0; i < length; i++) {
absoluteTokenAmountsData = abi.encodePacked(
absoluteTokenAmountsData,
keccak256(
abi.encode(
ABSOLUTE_TOKEN_AMOUNT_TYPEHASH,
absoluteTokenAmounts[i].token,
absoluteTokenAmounts[i].amount
)
)
);
}
return keccak256(absoluteTokenAmountsData);
}
function splitSignature(
bytes memory signature
)
internal
pure
returns (uint8 v, bytes32 r, bytes32 s)
{
require(signature.length == 65, "SV: bad signature");
assembly {
// first 32 bytes, after the length prefix.
r := mload(add(signature, 32))
// second 32 bytes.
s := mload(add(signature, 64))
// final byte (first byte of the next 32 bytes).
v := byte(0, mload(add(signature, 96)))
}
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
// Reference: github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/cryptography/ECDSA.sol
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
revert("SV: bad 's'");
}
if (v != 27 && v != 28) {
revert("SV: bad 'v'");
}
return (v, r, s);
}
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
// The struct consists of AbsoluteTokenAmount structs for
// (base) token and its underlying tokens (if any).
struct FullAbsoluteTokenAmount {
AbsoluteTokenAmountMeta base;
AbsoluteTokenAmountMeta[] underlying;
}
// The struct consists of AbsoluteTokenAmount struct
// with token address and absolute amount
// and ERC20Metadata struct with ERC20-style metadata.
// NOTE: 0xEeee...EEeE address is used for ETH.
struct AbsoluteTokenAmountMeta {
AbsoluteTokenAmount absoluteTokenAmount;
ERC20Metadata erc20metadata;
}
// The struct consists of ERC20-style token metadata.
struct ERC20Metadata {
string name;
string symbol;
uint8 decimals;
}
// The struct consists of protocol adapter's name
// and array of AbsoluteTokenAmount structs
// with token addresses and absolute amounts.
struct AdapterBalance {
bytes32 protocolAdapterName;
AbsoluteTokenAmount[] absoluteTokenAmounts;
}
// The struct consists of token address
// and its absolute amount.
struct AbsoluteTokenAmount {
address token;
uint256 amount;
}
// The struct consists of token address,
// and price per full share (1e18).
struct Component {
address token;
uint256 rate;
}
//=============================== Interactive Adapters Structs ====================================
struct TransactionData {
Action[] actions;
TokenAmount[] inputs;
Fee fee;
AbsoluteTokenAmount[] requiredOutputs;
uint256 nonce;
}
struct Action {
bytes32 protocolAdapterName;
ActionType actionType;
TokenAmount[] tokenAmounts;
bytes data;
}
struct TokenAmount {
address token;
uint256 amount;
AmountType amountType;
}
struct Fee {
uint256 share;
address beneficiary;
}
enum ActionType { None, Deposit, Withdraw }
enum AmountType { None, Relative, Absolute }// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
abstract contract Ownable {
modifier onlyOwner {
require(msg.sender == owner_, "O: only owner");
_;
}
modifier onlyPendingOwner {
require(msg.sender == pendingOwner_, "O: only pending owner");
_;
}
address private owner_;
address private pendingOwner_;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @notice Initializes owner variable with msg.sender address.
*/
constructor() internal {
owner_ = msg.sender;
emit OwnershipTransferred(address(0), msg.sender);
}
/**
* @notice Sets pending owner to the desired address.
* The function is callable only by the owner.
*/
function proposeOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "O: empty newOwner");
require(newOwner != owner_, "O: equal to owner_");
require(newOwner != pendingOwner_, "O: equal to pendingOwner_");
pendingOwner_ = newOwner;
}
/**
* @notice Transfers ownership to the pending owner.
* The function is callable only by the pending owner.
*/
function acceptOwnership() external onlyPendingOwner {
emit OwnershipTransferred(owner_, msg.sender);
owner_ = msg.sender;
delete pendingOwner_;
}
/**
* @return Owner of the contract.
*/
function owner() external view returns (address) {
return owner_;
}
/**
* @return Pending owner of the contract.
*/
function pendingOwner() external view returns (address) {
return pendingOwner_;
}
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
import { Action, AbsoluteTokenAmount, ActionType, AmountType } from "../shared/Structs.sol";
import { InteractiveAdapter } from "../interactiveAdapters/InteractiveAdapter.sol";
import { ERC20 } from "../shared/ERC20.sol";
import { ProtocolAdapterRegistry } from "./ProtocolAdapterRegistry.sol";
import { SafeERC20 } from "../shared/SafeERC20.sol";
import { Helpers } from "../shared/Helpers.sol";
import { ReentrancyGuard } from "./ReentrancyGuard.sol";
/**
* @title Main contract executing actions.
*/
contract Core is ReentrancyGuard {
using SafeERC20 for ERC20;
address internal immutable protocolAdapterRegistry_;
address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
event ExecutedAction(Action action);
constructor(
address protocolAdapterRegistry
)
public
{
require(protocolAdapterRegistry != address(0), "C: empty protocolAdapterRegistry");
protocolAdapterRegistry_ = protocolAdapterRegistry;
}
// solhint-disable-next-line no-empty-blocks
receive() external payable {}
/**
* @notice Executes actions and returns tokens to account.
* @param actions Array with actions to be executed.
* @param requiredOutputs Array with required amounts for the returned tokens.
* @param account Address that will receive all the resulting funds.
* @return actualOutputs Array with actual amounts for the returned tokens.
*/
function executeActions(
Action[] calldata actions,
AbsoluteTokenAmount[] calldata requiredOutputs,
address payable account
)
external
payable
nonReentrant
returns (AbsoluteTokenAmount[] memory)
{
require(account != address(0), "C: empty account");
address[][] memory tokensToBeWithdrawn = new address[][](actions.length);
for (uint256 i = 0; i < actions.length; i++) {
tokensToBeWithdrawn[i] = executeAction(actions[i]);
emit ExecutedAction(actions[i]);
}
return returnTokens(requiredOutputs, tokensToBeWithdrawn, account);
}
/**
* @notice Execute one action via external call.
* @param action Action struct.
* @dev Can be called only by this contract.
* This function is used to create cross-protocol adapters.
*/
function executeActionExternal(
Action calldata action
)
external
returns (address[] memory)
{
require(msg.sender == address(this), "C: only address(this)");
return executeAction(action);
}
/**
* @return Address of the ProtocolAdapterRegistry contract used.
*/
function protocolAdapterRegistry()
external
view
returns (address)
{
return protocolAdapterRegistry_;
}
function executeAction(
Action calldata action
)
internal
returns (address[] memory)
{
address adapter = ProtocolAdapterRegistry(protocolAdapterRegistry_).getProtocolAdapterAddress(
action.protocolAdapterName
);
require(adapter != address(0), "C: bad name");
require(
action.actionType == ActionType.Deposit || action.actionType == ActionType.Withdraw,
"C: bad action type"
);
bytes4 selector;
if (action.actionType == ActionType.Deposit) {
selector = InteractiveAdapter(adapter).deposit.selector;
} else {
selector = InteractiveAdapter(adapter).withdraw.selector;
}
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returnData) = adapter.delegatecall(
abi.encodeWithSelector(
selector,
action.tokenAmounts,
action.data
)
);
// assembly revert opcode is used here as `returnData`
// is already bytes array generated by the callee's revert()
// solhint-disable-next-line no-inline-assembly
assembly {
if eq(success, 0) { revert(add(returnData, 32), returndatasize()) }
}
return abi.decode(returnData, (address[]));
}
function returnTokens(
AbsoluteTokenAmount[] calldata requiredOutputs,
address[][] memory tokensToBeWithdrawn,
address payable account
)
internal
returns (AbsoluteTokenAmount[] memory)
{
uint256 length = requiredOutputs.length;
uint256 lengthNested;
address token;
AbsoluteTokenAmount[] memory actualOutputs = new AbsoluteTokenAmount[](length);
for (uint256 i = 0; i < length; i++) {
token = requiredOutputs[i].token;
actualOutputs[i] = AbsoluteTokenAmount({
token: token,
amount: checkRequirementAndTransfer(
token,
requiredOutputs[i].amount,
account
)
});
}
length = tokensToBeWithdrawn.length;
for (uint256 i = 0; i < length; i++) {
lengthNested = tokensToBeWithdrawn[i].length;
for (uint256 j = 0; j < lengthNested; j++) {
checkRequirementAndTransfer(tokensToBeWithdrawn[i][j], 0, account);
}
}
return actualOutputs;
}
function checkRequirementAndTransfer(
address token,
uint256 requiredAmount,
address account
)
internal
returns (uint256)
{
uint256 actualAmount;
if (token == ETH) {
actualAmount = address(this).balance;
} else {
actualAmount = ERC20(token).balanceOf(address(this));
}
require(
actualAmount >= requiredAmount,
string(
abi.encodePacked(
"C: ",
actualAmount,
" is less than ",
requiredAmount,
" for ",
token
)
)
);
if (actualAmount > 0) {
if (token == ETH) {
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = account.call{value: actualAmount}(new bytes(0));
require(success, "ETH transfer to account failed");
} else {
ERC20(token).safeTransfer(account, actualAmount, "C");
}
}
return actualAmount;
}
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
import { ProtocolAdapter } from "../adapters/ProtocolAdapter.sol";
import { TokenAmount, AmountType } from "../shared/Structs.sol";
import { ERC20 } from "../shared/ERC20.sol";
/**
* @title Base contract for interactive protocol adapters.
* @dev deposit() and withdraw() functions MUST be implemented
* as well as all the functions from ProtocolAdapter abstract contract.
* @author Igor Sobolev <[email protected]>
*/
abstract contract InteractiveAdapter is ProtocolAdapter {
uint256 internal constant DELIMITER = 1e18;
address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/**
* @dev The function must deposit assets to the protocol.
* @return MUST return assets to be sent back to the `msg.sender`.
*/
function deposit(
TokenAmount[] memory tokenAmounts,
bytes memory data
)
public
payable
virtual
returns (address[] memory);
/**
* @dev The function must withdraw assets from the protocol.
* @return MUST return assets to be sent back to the `msg.sender`.
*/
function withdraw(
TokenAmount[] memory tokenAmounts,
bytes memory data
)
public
payable
virtual
returns (address[] memory);
function getAbsoluteAmountDeposit(
TokenAmount memory tokenAmount
)
internal
view
virtual
returns (uint256)
{
address token = tokenAmount.token;
uint256 amount = tokenAmount.amount;
AmountType amountType = tokenAmount.amountType;
require(
amountType == AmountType.Relative || amountType == AmountType.Absolute,
"IA: bad amount type"
);
if (amountType == AmountType.Relative) {
require(amount <= DELIMITER, "IA: bad amount");
uint256 balance;
if (token == ETH) {
balance = address(this).balance;
} else {
balance = ERC20(token).balanceOf(address(this));
}
if (amount == DELIMITER) {
return balance;
} else {
return mul(balance, amount) / DELIMITER;
}
} else {
return amount;
}
}
function getAbsoluteAmountWithdraw(
TokenAmount memory tokenAmount
)
internal
view
virtual
returns (uint256)
{
address token = tokenAmount.token;
uint256 amount = tokenAmount.amount;
AmountType amountType = tokenAmount.amountType;
require(
amountType == AmountType.Relative || amountType == AmountType.Absolute,
"IA: bad amount type"
);
if (amountType == AmountType.Relative) {
require(amount <= DELIMITER, "IA: bad amount");
uint256 balance = getBalance(token, address(this));
if (amount == DELIMITER) {
return balance;
} else {
return mul(balance, amount) / DELIMITER;
}
} else {
return amount;
}
}
function mul(
uint256 a,
uint256 b
)
internal
pure
returns (uint256)
{
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "IA: mul overflow");
return c;
}
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io> // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. // // SPDX-License-Identifier: LGPL-3.0-only pragma solidity 0.6.11; pragma experimental ABIEncoderV2; /** * @title Protocol adapter abstract contract. * @dev adapterType(), tokenType(), and getBalance() functions MUST be implemented. * @author Igor Sobolev <[email protected]> */ abstract contract ProtocolAdapter { /** * @dev MUST return amount and type of the given token * locked on the protocol by the given account. */ function getBalance( address token, address account ) public view virtual returns (uint256); }
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
import { AdapterBalance, AbsoluteTokenAmount } from "../shared/Structs.sol";
import { ERC20 } from "../shared/ERC20.sol";
import { Ownable } from "./Ownable.sol";
import { ProtocolAdapterManager } from "./ProtocolAdapterManager.sol";
import { ProtocolAdapter } from "../adapters/ProtocolAdapter.sol";
/**
* @title Registry for protocol adapters.
* @notice getBalances() function implements the main functionality.
* @author Igor Sobolev <[email protected]>
*/
contract ProtocolAdapterRegistry is Ownable, ProtocolAdapterManager {
address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/**
* @param account Address of the account.
* @return AdapterBalance array by the given account.
* @notice Zero values are filtered out!
*/
function getBalances(
address account
)
external
view
returns (AdapterBalance[] memory)
{
// Get balances for all the adapters
AdapterBalance[] memory adapterBalances = getAdapterBalances(
_protocolAdapterNames,
account
);
// Declare temp variable and counters
AbsoluteTokenAmount[] memory currentAbsoluteTokenAmounts;
AbsoluteTokenAmount[] memory nonZeroAbsoluteTokenAmounts;
uint256 nonZeroAdaptersCounter;
uint256[] memory nonZeroTokensCounters;
uint256 adapterBalancesLength;
uint256 currentAbsoluteTokenAmountsLength;
// Reset counters
nonZeroTokensCounters = new uint256[](adapterBalances.length);
nonZeroAdaptersCounter = 0;
adapterBalancesLength = adapterBalances.length;
// Iterate over all the adapters' balances
for (uint256 i = 0; i < adapterBalancesLength; i++) {
// Fill temp variable
currentAbsoluteTokenAmounts = adapterBalances[i].absoluteTokenAmounts;
// Reset counter
nonZeroTokensCounters[i] = 0;
currentAbsoluteTokenAmountsLength = currentAbsoluteTokenAmounts.length;
// Increment if token balance is positive
for (uint256 j = 0; j < currentAbsoluteTokenAmountsLength; j++) {
if (currentAbsoluteTokenAmounts[j].amount > 0) {
nonZeroTokensCounters[i]++;
}
}
// Increment if at least one positive token balance
if (nonZeroTokensCounters[i] > 0) {
nonZeroAdaptersCounter++;
}
}
// Declare resulting variable
AdapterBalance[] memory nonZeroAdapterBalances;
// Reset resulting variable and counter
nonZeroAdapterBalances = new AdapterBalance[](nonZeroAdaptersCounter);
nonZeroAdaptersCounter = 0;
// Iterate over all the adapters' balances
for (uint256 i = 0; i < adapterBalancesLength; i++) {
// Skip if no positive token balances
if (nonZeroTokensCounters[i] == 0) {
continue;
}
// Fill temp variable
currentAbsoluteTokenAmounts = adapterBalances[i].absoluteTokenAmounts;
// Reset temp variable and counter
nonZeroAbsoluteTokenAmounts = new AbsoluteTokenAmount[](nonZeroTokensCounters[i]);
nonZeroTokensCounters[i] = 0;
currentAbsoluteTokenAmountsLength = currentAbsoluteTokenAmounts.length;
for (uint256 j = 0; j < currentAbsoluteTokenAmountsLength; j++) {
// Skip if balance is not positive
if (currentAbsoluteTokenAmounts[j].amount == 0) {
continue;
}
// Else fill temp variable
nonZeroAbsoluteTokenAmounts[nonZeroTokensCounters[i]] = currentAbsoluteTokenAmounts[j];
// Increment counter
nonZeroTokensCounters[i]++;
}
// Fill resulting variable
nonZeroAdapterBalances[nonZeroAdaptersCounter] = AdapterBalance({
protocolAdapterName: adapterBalances[i].protocolAdapterName,
absoluteTokenAmounts: nonZeroAbsoluteTokenAmounts
});
// Increment counter
nonZeroAdaptersCounter++;
}
return nonZeroAdapterBalances;
}
/**
* @param protocolAdapterNames Array of the protocol adapters' names.
* @param account Address of the account.
* @return AdapterBalance array by the given parameters.
*/
function getAdapterBalances(
bytes32[] memory protocolAdapterNames,
address account
)
public
view
returns (AdapterBalance[] memory)
{
uint256 length = protocolAdapterNames.length;
AdapterBalance[] memory adapterBalances = new AdapterBalance[](length);
for (uint256 i = 0; i < length; i++) {
adapterBalances[i] = getAdapterBalance(
protocolAdapterNames[i],
_protocolAdapterSupportedTokens[protocolAdapterNames[i]],
account
);
}
return adapterBalances;
}
/**
* @param protocolAdapterName Protocol adapter's Name.
* @param tokens Array of tokens' addresses.
* @param account Address of the account.
* @return AdapterBalance array by the given parameters.
*/
function getAdapterBalance(
bytes32 protocolAdapterName,
address[] memory tokens,
address account
)
public
view
returns (AdapterBalance memory)
{
address adapter = _protocolAdapterAddress[protocolAdapterName];
require(adapter != address(0), "AR: bad protocolAdapterName");
uint256 length = tokens.length;
AbsoluteTokenAmount[] memory absoluteTokenAmounts = new AbsoluteTokenAmount[](tokens.length);
for (uint256 i = 0; i < length; i++) {
try ProtocolAdapter(adapter).getBalance(
tokens[i],
account
) returns (uint256 amount) {
absoluteTokenAmounts[i] = AbsoluteTokenAmount({
token: tokens[i],
amount: amount
});
} catch {
absoluteTokenAmounts[i] = AbsoluteTokenAmount({
token: tokens[i],
amount: 0
});
}
}
return AdapterBalance({
protocolAdapterName: protocolAdapterName,
absoluteTokenAmounts: absoluteTokenAmounts
});
}
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
import { Ownable } from "./Ownable.sol";
/**
* @title ProtocolAdapterRegistry part responsible for protocol adapters management.
* @dev Base contract for ProtocolAdapterRegistry.
* @author Igor Sobolev <[email protected]>
*/
abstract contract ProtocolAdapterManager is Ownable {
// Protocol adapters' names
bytes32[] internal _protocolAdapterNames;
// Protocol adapter's name => protocol adapter's address
mapping (bytes32 => address) internal _protocolAdapterAddress;
// protocol adapter's name => protocol adapter's supported tokens
mapping (bytes32 => address[]) internal _protocolAdapterSupportedTokens;
/**
* @notice Adds protocol adapters.
* The function is callable only by the owner.
* @param newProtocolAdapterNames Array of the new protocol adapters' names.
* @param newProtocolAdapterAddresses Array of the new protocol adapters' addresses.
* @param newSupportedTokens Array of the new protocol adapters' supported tokens.
*/
function addProtocolAdapters(
bytes32[] calldata newProtocolAdapterNames,
address[] calldata newProtocolAdapterAddresses,
address[][] calldata newSupportedTokens
)
external
onlyOwner
{
uint256 length = newProtocolAdapterNames.length;
require(length != 0, "PAM: empty[1]");
require(length == newProtocolAdapterAddresses.length, "PAM: lengths differ[1]");
require(length == newSupportedTokens.length, "PAM: lengths differ[2]");
for (uint256 i = 0; i < length; i++) {
addProtocolAdapter(
newProtocolAdapterNames[i],
newProtocolAdapterAddresses[i],
newSupportedTokens[i]
);
}
}
/**
* @notice Removes protocol adapters.
* The function is callable only by the owner.
* @param protocolAdapterNames Array of the protocol adapters' names.
*/
function removeProtocolAdapters(
bytes32[] calldata protocolAdapterNames
)
external
onlyOwner
{
uint256 length = protocolAdapterNames.length;
require(length != 0, "PAM: empty[2]");
for (uint256 i = 0; i < length; i++) {
removeProtocolAdapter(protocolAdapterNames[i]);
}
}
/**
* @notice Updates protocol adapters.
* The function is callable only by the owner.
* @param protocolAdapterNames Array of the protocol adapters' names.
* @param newProtocolAdapterAddresses Array of the protocol adapters' new addresses.
* @param newSupportedTokens Array of the protocol adapters' new supported tokens.
*/
function updateProtocolAdapters(
bytes32[] calldata protocolAdapterNames,
address[] calldata newProtocolAdapterAddresses,
address[][] calldata newSupportedTokens
)
external
onlyOwner
{
uint256 length = protocolAdapterNames.length;
require(length != 0, "PAM: empty[3]");
require(length == newProtocolAdapterAddresses.length, "PAM: lengths differ[3]");
require(length == newSupportedTokens.length, "PAM: lengths differ[4]");
for (uint256 i = 0; i < length; i++) {
updateProtocolAdapter(
protocolAdapterNames[i],
newProtocolAdapterAddresses[i],
newSupportedTokens[i]
);
}
}
/**
* @return Array of protocol adapters' names.
*/
function getProtocolAdapterNames()
external
view
returns (bytes32[] memory)
{
return _protocolAdapterNames;
}
/**
* @param protocolAdapterName Name of the protocol adapter.
* @return Address of protocol adapter.
*/
function getProtocolAdapterAddress(
bytes32 protocolAdapterName
)
external
view
returns (address)
{
return _protocolAdapterAddress[protocolAdapterName];
}
/**
* @param protocolAdapterName Name of the protocol adapter.
* @return Array of protocol adapter's supported tokens.
*/
function getSupportedTokens(
bytes32 protocolAdapterName
)
external
view
returns (address[] memory)
{
return _protocolAdapterSupportedTokens[protocolAdapterName];
}
/**
* @notice Adds a protocol adapter.
* @param newProtocolAdapterName New protocol adapter's protocolAdapterName.
* @param newAddress New protocol adapter's address.
* @param newSupportedTokens Array of the new protocol adapter's supported tokens.
* Empty array is always allowed.
*/
function addProtocolAdapter(
bytes32 newProtocolAdapterName,
address newAddress,
address[] calldata newSupportedTokens
)
internal
{
require(newProtocolAdapterName != bytes32(0), "PAM: zero[1]");
require(newAddress != address(0), "PAM: zero[2]");
require(_protocolAdapterAddress[newProtocolAdapterName] == address(0), "PAM: exists");
_protocolAdapterNames.push(newProtocolAdapterName);
_protocolAdapterAddress[newProtocolAdapterName] = newAddress;
_protocolAdapterSupportedTokens[newProtocolAdapterName] = newSupportedTokens;
}
/**
* @notice Removes a protocol adapter.
* @param protocolAdapterName Protocol adapter's protocolAdapterName.
*/
function removeProtocolAdapter(
bytes32 protocolAdapterName
)
internal
{
require(_protocolAdapterAddress[protocolAdapterName] != address(0), "PAM: does not exist[1]");
uint256 length = _protocolAdapterNames.length;
uint256 index = 0;
while (_protocolAdapterNames[index] != protocolAdapterName) {
index++;
}
if (index != length - 1) {
_protocolAdapterNames[index] = _protocolAdapterNames[length - 1];
}
_protocolAdapterNames.pop();
delete _protocolAdapterAddress[protocolAdapterName];
delete _protocolAdapterSupportedTokens[protocolAdapterName];
}
/**
* @notice Updates a protocol adapter.
* @param protocolAdapterName Protocol adapter's protocolAdapterName.
* @param newProtocolAdapterAddress Protocol adapter's new address.
* @param newSupportedTokens Array of the protocol adapter's new supported tokens.
* Empty array is always allowed.
*/
function updateProtocolAdapter(
bytes32 protocolAdapterName,
address newProtocolAdapterAddress,
address[] calldata newSupportedTokens
)
internal
{
address oldProtocolAdapterAddress = _protocolAdapterAddress[protocolAdapterName];
require(oldProtocolAdapterAddress != address(0), "PAM: does not exist[2]");
require(newProtocolAdapterAddress != address(0), "PAM: zero[3]");
if (oldProtocolAdapterAddress == newProtocolAdapterAddress) {
_protocolAdapterSupportedTokens[protocolAdapterName] = newSupportedTokens;
} else {
_protocolAdapterAddress[protocolAdapterName] = newProtocolAdapterAddress;
_protocolAdapterSupportedTokens[protocolAdapterName] = newSupportedTokens;
}
}
}// Copyright (C) 2020 Zerion Inc. <https://zerion.io> // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. // // SPDX-License-Identifier: LGPL-3.0-only pragma solidity 0.6.11; pragma experimental ABIEncoderV2; /** * @notice Library helps to convert different types to strings. * @author Igor Sobolev <[email protected]> */ library Helpers { /** * @dev Internal function to convert bytes32 to string and trim zeroes. */ function toString(bytes32 data) internal pure returns (string memory) { uint256 counter = 0; for (uint256 i = 0; i < 32; i++) { if (data[i] != bytes1(0)) { counter++; } } bytes memory result = new bytes(counter); counter = 0; for (uint256 i = 0; i < 32; i++) { if (data[i] != bytes1(0)) { result[counter] = data[i]; counter++; } } return string(result); } /** * @dev Internal function to convert uint256 to string. */ function toString(uint256 data) internal pure returns (string memory) { uint256 length = 0; uint256 dataCopy = data; while (dataCopy != 0) { length++; dataCopy /= 10; } bytes memory result = new bytes(length); dataCopy = data; // Here, we have on-purpose underflow cause we need case `i = 0` to be included in the loop for (uint256 i = length - 1; i < length; i--) { result[i] = bytes1(uint8(48 + dataCopy % 10)); dataCopy /= 10; } return string(result); } }
// Copyright (C) 2020 Zerion Inc. <https://zerion.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;
contract ReentrancyGuard {
uint256 internal constant UNLOCKED = 1;
uint256 internal constant LOCKED = 2;
uint256 internal guard_;
constructor () internal {
guard_ = UNLOCKED;
}
modifier nonReentrant() {
require(guard_ == UNLOCKED, "RG: locked");
guard_ = LOCKED;
_;
guard_ = UNLOCKED;
}
}{
"optimizer": {
"enabled": true,
"runs": 1000000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"remappings": []
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address payable","name":"core","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"core","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"bytes32","name":"protocolAdapterName","type":"bytes32"},{"internalType":"enum ActionType","name":"actionType","type":"uint8"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AmountType","name":"amountType","type":"uint8"}],"internalType":"struct TokenAmount[]","name":"tokenAmounts","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Action[]","name":"actions","type":"tuple[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AmountType","name":"amountType","type":"uint8"}],"internalType":"struct TokenAmount[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"share","type":"uint256"},{"internalType":"address","name":"beneficiary","type":"address"}],"internalType":"struct Fee","name":"fee","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct AbsoluteTokenAmount[]","name":"requiredOutputs","type":"tuple[]"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"internalType":"struct TransactionData","name":"data","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"getAccountFromSignature","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AmountType","name":"amountType","type":"uint8"}],"internalType":"struct TokenAmount[]","name":"inputs","type":"tuple[]"},{"internalType":"address","name":"account","type":"address"}],"name":"getRequiredAllowances","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct AbsoluteTokenAmount[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AmountType","name":"amountType","type":"uint8"}],"internalType":"struct TokenAmount[]","name":"inputs","type":"tuple[]"},{"internalType":"address","name":"account","type":"address"}],"name":"getRequiredBalances","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct AbsoluteTokenAmount[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"proposeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"returnLostTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"protocolAdapterName","type":"bytes32"},{"internalType":"enum ActionType","name":"actionType","type":"uint8"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AmountType","name":"amountType","type":"uint8"}],"internalType":"struct TokenAmount[]","name":"tokenAmounts","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Action[]","name":"actions","type":"tuple[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AmountType","name":"amountType","type":"uint8"}],"internalType":"struct TokenAmount[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"share","type":"uint256"},{"internalType":"address","name":"beneficiary","type":"address"}],"internalType":"struct Fee","name":"fee","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct AbsoluteTokenAmount[]","name":"requiredOutputs","type":"tuple[]"}],"name":"startExecution","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct AbsoluteTokenAmount[]","name":"","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"bytes32","name":"protocolAdapterName","type":"bytes32"},{"internalType":"enum ActionType","name":"actionType","type":"uint8"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AmountType","name":"amountType","type":"uint8"}],"internalType":"struct TokenAmount[]","name":"tokenAmounts","type":"tuple[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Action[]","name":"actions","type":"tuple[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AmountType","name":"amountType","type":"uint8"}],"internalType":"struct TokenAmount[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"share","type":"uint256"},{"internalType":"address","name":"beneficiary","type":"address"}],"internalType":"struct Fee","name":"fee","type":"tuple"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct AbsoluteTokenAmount[]","name":"requiredOutputs","type":"tuple[]"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"internalType":"struct TransactionData","name":"data","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"startExecution","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct AbsoluteTokenAmount[]","name":"","type":"tuple[]"}],"stateMutability":"payable","type":"function"}]Contract Creation Code
60c06040523480156200001157600080fd5b50604051620037dc380380620037dc833981016040819052620000349162000162565b6040518060400160405280600d81526020016c2d32b934b7b7102937baba32b960991b8152506040516020016200006b90620001ce565b604051602081830303815290604052805190602001208160405160200162000094919062000192565b6040516020818303038152906040528051906020012030604051602001620000bf939291906200022c565b60408051601f19818403018152908290528051602090910120608052600180546001600160a01b0319163390811790915591506000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36001600160a01b0381166200014c5760405162461bcd60e51b815260040162000143906200024b565b60405180910390fd5b60601b6001600160601b03191660a05262000272565b60006020828403121562000174578081fd5b81516001600160a01b03811681146200018b578182fd5b9392505050565b60008251815b81811015620001b4576020818601810151858301520162000198565b81811115620001c35782828501525b509190910192915050565b6c08a92a06e626488dedac2d2dc5609b1b81526b1cdd1c9a5b99c81b985b594b60a21b600d8201527f6164647265737320766572696679696e67436f6e7472616374000000000000006019820152602960f81b603282015260330190565b92835260208301919091526001600160a01b0316604082015260600190565b6020808252600d908201526c523a20656d70747920636f726560981b604082015260600190565b60805160a05160601c613534620002a860003980610cc75280610d0d52806115f9528061172a52508061076352506135346000f3fe6080604052600436106100c75760003560e01c80638da5cb5b11610074578063e6096b4d1161004e578063e6096b4d146101e3578063e89db67114610203578063f2f4eb2614610223576100c7565b80638da5cb5b1461018c578063a4592161146101ae578063e30c3978146101ce576100c7565b8063710bf322116100a5578063710bf3221461014257806379ba5097146101645780638042c01f14610179576100c7565b80631b277241146100cc5780636b72b8cf146100f557806370ae92d214610115575b600080fd5b6100df6100da366004612406565b610238565b6040516100ec9190612e31565b60405180910390f35b34801561010157600080fd5b506100df61011036600461249c565b610252565b34801561012157600080fd5b506101356101303660046122f0565b610419565b6040516100ec9190613445565b34801561014e57600080fd5b5061016261015d3660046122f0565b610445565b005b34801561017057600080fd5b506101626105dd565b6100df610187366004612559565b6106ab565b34801561019857600080fd5b506101a16106eb565b6040516100ec9190612d92565b3480156101ba57600080fd5b506101a16101c9366004612559565b610707565b3480156101da57600080fd5b506101a16108e2565b3480156101ef57600080fd5b506100df6101fe36600461249c565b6108fe565b34801561020f57600080fd5b5061016261021e36600461230c565b610a9e565b34801561022f57600080fd5b506101a1610cc5565b60606102478585858533610ce9565b90505b949350505050565b606082818167ffffffffffffffff8111801561026d57600080fd5b506040519080825280602002602001820160405280156102a757816020015b610294611fa0565b81526020019060019003908161028c5790505b509050600080805b8481101561040c576102e28989838181106102c657fe5b9050606002018036038101906102dc919061253e565b88610e84565b92508888828181106102f057fe5b61030692602060609092020190810191506122f0565b73ffffffffffffffffffffffffffffffffffffffff166370a08231886040518263ffffffff1660e01b815260040161033e9190612d92565b60206040518083038186803b15801561035657600080fd5b505afa15801561036a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038e919061264a565b915060405180604001604052808a8a848181106103a757fe5b6103bd92602060609092020190810191506122f0565b73ffffffffffffffffffffffffffffffffffffffff1681526020018385116103e65760006103ea565b8385035b8152508482815181106103f957fe5b60209081029190910101526001016102af565b5091979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020545b919050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461049f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906130e6565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166104ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613078565b60015473ffffffffffffffffffffffffffffffffffffffff82811691161415610541576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613230565b60025473ffffffffffffffffffffffffffffffffffffffff82811691161415610596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613154565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60025473ffffffffffffffffffffffffffffffffffffffff16331461062e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613267565b600154604051339173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000009081163317909155600280549091169055565b606060006106b98484610707565b90506106c4816110b9565b6106e1846000015185602001518660400151876060015185610ce9565b9150505b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b600080600080610716856110e6565b9194509250905060007f19000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061078b8a6111ed565b60405160200161079e9493929190612761565b6040516020818303038152906040528051906020012090506000600182868686604051600081526020016040526040516107db9493929190613047565b6020604051602081039080840390855afa1580156107fd573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610875576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613369565b608088015173ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054146108d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906131f9565b979650505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff1690565b606082818167ffffffffffffffff8111801561091957600080fd5b5060405190808252806020026020018201604052801561095357816020015b610940611fa0565b8152602001906001900390816109385790505b509050600080805b8481101561040c576109728989838181106102c657fe5b925088888281811061098057fe5b61099692602060609092020190810191506122f0565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e88306040518363ffffffff1660e01b81526004016109d0929190612db3565b60206040518083038186803b1580156109e857600080fd5b505afa1580156109fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a20919061264a565b915060405180604001604052808a8a84818110610a3957fe5b610a4f92602060609092020190810191506122f0565b73ffffffffffffffffffffffffffffffffffffffff168152602001838511610a78576000610a7c565b8385035b815250848281518110610a8b57fe5b602090810291909101015260010161095b565b60015473ffffffffffffffffffffffffffffffffffffffff163314610aef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906130e6565b73ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610bdb576040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff8316904790604051610b5891906127a3565b60006040518083038185875af1925050503d8060008114610b95576040519150601f19603f3d011682016040523d82523d6000602084013e610b9a565b606091505b5050905080610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906130af565b50610cc1565b610cc1818373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c189190612d92565b60206040518083038186803b158015610c3057600080fd5b505afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c68919061264a565b60408051808201909152600181527f5200000000000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff861692919063ffffffff61133616565b5050565b7f000000000000000000000000000000000000000000000000000000000000000090565b606060005a9050610cfb8686856113f4565b6060610d0785886117fa565b905060607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663695f72198a84886040518463ffffffff1660e01b8152600401610d6893929190612e44565b600060405180830381600087803b158015610d8257600080fd5b505af1158015610d96573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610ddc9190810190612344565b90506000601036025a8561520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff16636366b93661a0aa8361374a0181610e2757fe5b046040518263ffffffff1660e01b8152600401610e449190613445565b600060405180830381600087803b158015610e5e57600080fd5b505af1158015610e72573d6000803e3d6000fd5b50939c9b505050505050505050505050565b81516040830151602084015160009291906001826002811115610ea357fe5b1480610eba57506002826002811115610eb857fe5b145b610ef0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061329e565b6001826002811115610efe57fe5b14156110af57670de0b6b3a7640000811115610f46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906131c2565b670de0b6b3a7640000811415611002576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190610fa8908890600401612d92565b60206040518083038186803b158015610fc057600080fd5b505afa158015610fd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff8919061264a565b93505050506106e5565b670de0b6b3a764000061109d8473ffffffffffffffffffffffffffffffffffffffff166370a08231886040518263ffffffff1660e01b81526004016110479190612d92565b60206040518083038186803b15801561105f57600080fd5b505afa158015611073573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611097919061264a565b8361198b565b816110a457fe5b0493505050506106e5565b92506106e5915050565b73ffffffffffffffffffffffffffffffffffffffff16600090815260208190526040902080546001019055565b60008060008351604114611126576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613369565b50505060208101516040820151606083015160001a91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115611197576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906132d5565b8260ff16601b141580156111af57508260ff16601c14155b156111e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061311d565b9193909250565b60006040516020016111fe906129ff565b60405160208183030381529060405260405160200161121c90612c36565b60405160208183030381529060405260405160200161123a90612918565b6040516020818303038152906040526040516020016112589061287d565b60405160208183030381529060405260405160200161127690612cd1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526112b5959493929160200161280f565b604051602081830303815290604052805190602001206112d883600001516119e6565b6112e58460200151611b74565b6112f28560400151611c70565b6112ff8660600151611cb3565b866080015160405160200161131996959493929190612fbf565b604051602081830303815290604052805190602001209050919050565b6113ee8463a9059cbb60e01b8585604051602401611355929190612e0b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060400160405280600881526020017f7472616e7366657200000000000000000000000000000000000000000000000081525084611d96565b50505050565b8251825160009182918291901561149857602086015173ffffffffffffffffffffffffffffffffffffffff16611456576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906130af565b8551662386f26fc100001015611498576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906133a0565b60005b81811015611630578781815181106114af57fe5b60200260200101516000015194506114da8882815181106114cc57fe5b602002602001015187610e84565b935060008411611516576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061318b565b670de0b6b3a764000061152d85896000015161198b565b8161153457fe5b04925082156115a5576115a5868860200151856040518060400160405280600481526020017f525b315d000000000000000000000000000000000000000000000000000000008152508973ffffffffffffffffffffffffffffffffffffffff16611edf90949392919063ffffffff16565b60408051808201909152600481527f525b325d0000000000000000000000000000000000000000000000000000000060208201526116289073ffffffffffffffffffffffffffffffffffffffff87169088907f0000000000000000000000000000000000000000000000000000000000000000908789039063ffffffff611edf16565b60010161149b565b5034156117f157670de0b6b3a764000061164e34886000015161198b565b8161165557fe5b0491508115611718576020868101516040805160008082529381019182905273ffffffffffffffffffffffffffffffffffffffff90921691859161169991906127a3565b60006040518083038185875af1925050503d80600081146116d6576040519150601f19603f3d011682016040523d82523d6000602084013e6116db565b606091505b5050905080611716576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061330c565b505b604080516000808252602082019092527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690348590039060405161177291906127a3565b60006040518083038185875af1925050503d80600081146117af576040519150601f19603f3d011682016040523d82523d6000602084013e6117b4565b606091505b50509050806117ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061340e565b505b50505050505050565b6060600080341161180c57600061180f565b60015b60ff16905060608184518651010167ffffffffffffffff8111801561183357600080fd5b5060405190808252806020026020018201604052801561186d57816020015b61185a611fa0565b8152602001906001900390816118525790505b50905060005b85518110156118af5785818151811061188857fe5b602002602001015182828151811061189c57fe5b6020908102919091010152600101611873565b5060005b84518110156119215760405180604001604052808683815181106118d357fe5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168152602001600081525082828851018151811061190e57fe5b60209081029190910101526001016118b3565b5081156106e157604051806040016040528073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff16815260200160008152508185518751018151811061197857fe5b6020026020010181905250949350505050565b60008261199a575060006106e5565b828202828482816119a757fe5b04146119df576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906133d7565b9392505050565b604080516000808252602082019092528251825b81811015611b645782604051602001611a1290612918565b604051602081830303815290604052604051602001611a3090612cd1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611a6c92916020016127e1565b60405160208183030381529060405280519060200120868381518110611a8e57fe5b602002602001015160000151878481518110611aa657fe5b602002602001015160200151611ad2898681518110611ac157fe5b602002602001015160400151611b74565b898681518110611ade57fe5b60200260200101516060015180519060200120604051602001611b05959493929190612fe7565b60405160208183030381529060405280519060200120604051602001611b2c9291906127bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905292506001016119fa565b5050805160209091012092915050565b604080516000808252602082019092528251825b81811015611b645782604051602001611ba090612cd1565b60405160208183030381529060405280519060200120868381518110611bc257fe5b602002602001015160000151878481518110611bda57fe5b602002602001015160200151888581518110611bf257fe5b602002602001015160400151604051602001611c119493929190612f7e565b60405160208183030381529060405280519060200120604051602001611c389291906127bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529250600101611b88565b6000604051602001611c819061287d565b60405160208183030381529060405280519060200120826000015183602001516040516020016113199392919061301b565b604080516000808252602082019092528251825b81811015611b645782604051602001611cdf90612c36565b60405160208183030381529060405280519060200120868381518110611d0157fe5b602002602001015160000151878481518110611d1957fe5b602002602001015160200151604051602001611d3793929190612f52565b60405160208183030381529060405280519060200120604051602001611d5e9291906127bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529250600101611cc7565b600060608573ffffffffffffffffffffffffffffffffffffffff1685604051611dbf91906127a3565b6000604051808303816000865af19150503d8060008114611dfc576040519150601f19603f3d011682016040523d82523d6000602084013e611e01565b606091505b5091509150818484604051602001611e1a929190612bb4565b60405160208183030381529060405290611e61576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969190613065565b50805115611ed75780806020019051810190611e7d919061251e565b8484604051602001611e90929190612b32565b604051602081830303815290604052906117f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969190613065565b505050505050565b611f99856323b872dd60e01b868686604051602401611f0093929190612dda565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060400160405280600c81526020017f7472616e7366657246726f6d000000000000000000000000000000000000000081525084611d96565b5050505050565b604080518082019091526000808252602082015290565b80356106e5816134cc565b80516106e5816134cc565b600082601f830112611fdd578081fd5b8135611ff0611feb82613475565b61344e565b818152915060208083019084810160408085028701830188101561201357600080fd5b6000805b8681101561205c5782848b03121561202d578182fd5b6120368361344e565b6120408b86611fb7565b8152848601358682015286529484019492820192600101612017565b5050505050505092915050565b600082601f830112612079578081fd5b8135612087611feb82613475565b818152915060208083019084810160005b8481101561216357813587016080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838c030112156120d757600080fd5b6120e08161344e565b8583013581526040808401356120f5816134f1565b8288015260608481013567ffffffffffffffff8082111561211557600080fd5b6121238f8b848a010161216e565b848601528587013593508084111561213a57600080fd5b505061214a8d89848801016121e2565b9083015250865250509282019290820190600101612098565b505050505092915050565b600082601f83011261217e578081fd5b813561218c611feb82613475565b81815291506020808301908481016060808502870183018810156121af57600080fd5b60005b858110156121d6576121c489846122a3565b855293830193918101916001016121b2565b50505050505092915050565b600082601f8301126121f2578081fd5b813567ffffffffffffffff811115612208578182fd5b61223960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161344e565b915080825283602082850101111561225057600080fd5b8060208401602084013760009082016020015292915050565b60006040828403121561227a578081fd5b612284604061344e565b9050813581526020820135612298816134cc565b602082015292915050565b6000606082840312156122b4578081fd5b6122be606061344e565b905081356122cb816134cc565b81526020828101359082015260408201356122e5816134f1565b604082015292915050565b600060208284031215612301578081fd5b81356119df816134cc565b6000806040838503121561231e578081fd5b8235612329816134cc565b91506020830135612339816134cc565b809150509250929050565b60006020808385031215612356578182fd5b825167ffffffffffffffff81111561236c578283fd5b80840185601f82011261237d578384fd5b8051915061238d611feb83613475565b828152838101908285016040808602850187018a10156123ab578788fd5b8794505b858510156123f85780828b0312156123c5578788fd5b6123ce8161344e565b6123d88b84611fc2565b8152828801518882015284526001949094019392860192908101906123af565b509098975050505050505050565b60008060008060a0858703121561241b578182fd5b843567ffffffffffffffff80821115612432578384fd5b61243e88838901612069565b95506020870135915080821115612453578384fd5b61245f8883890161216e565b945061246e8860408901612269565b93506080870135915080821115612483578283fd5b5061249087828801611fcd565b91505092959194509250565b6000806000604084860312156124b0578081fd5b833567ffffffffffffffff808211156124c7578283fd5b81860187601f8201126124d8578384fd5b80359250818311156124e8578384fd5b8760206060850283010111156124fc578384fd5b6020908101955091935050840135612513816134cc565b809150509250925092565b60006020828403121561252f578081fd5b815180151581146119df578182fd5b60006060828403121561254f578081fd5b6119df83836122a3565b6000806040838503121561256b578182fd5b823567ffffffffffffffff80821115612582578384fd5b81850160c08188031215612594578485fd5b61259e60a061344e565b92508035828111156125ae578586fd5b6125ba88828401612069565b8452506020810135828111156125ce578586fd5b6125da8882840161216e565b6020850152506125ed8760408301612269565b6040840152608081013582811115612603578586fd5b61260f88828401611fcd565b60608501525060a00135608083015290925060208401359080821115612633578283fd5b50612640858286016121e2565b9150509250929050565b60006020828403121561265b578081fd5b5051919050565b600073ffffffffffffffffffffffffffffffffffffffff8251168352602082015160208401526126956040830151613495565b6040840152505060600190565b73ffffffffffffffffffffffffffffffffffffffff169052565b6000815180845260208085019450808401835b8381101561270c578151805173ffffffffffffffffffffffffffffffffffffffff16885283015183880152604090960195908201906001016126cf565b509495945050505050565b6000815180845261272f8160208601602086016134a0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fff0000000000000000000000000000000000000000000000000000000000000094851681529290931660018301526002820152602281019190915260420190565b600082516127b58184602087016134a0565b9190910192915050565b600083516127d18184602088016134a0565b9190910191825250602001919050565b600083516127f38184602088016134a0565b83519083016128068282602088016134a0565b01949350505050565b60008651612821818460208b016134a0565b8651908301612834828260208b016134a0565b8651918101612847838260208b016134a0565b86519201905061285b8282602089016134a0565b845191810161286e8382602089016134a0565b90910198975050505050505050565b7f466565280000000000000000000000000000000000000000000000000000000081527f75696e743235362073686172652c00000000000000000000000000000000000060048201527f616464726573732062656e65666963696172790000000000000000000000000060128201527f2900000000000000000000000000000000000000000000000000000000000000602582015260260190565b7f416374696f6e280000000000000000000000000000000000000000000000000081527f627974657333322070726f746f636f6c416461707465724e616d652c0000000060078201527f75696e743820616374696f6e547970652c00000000000000000000000000000060238201527f546f6b656e416d6f756e745b5d20746f6b656e416d6f756e74732c000000000060348201527f6279746573206461746100000000000000000000000000000000000000000000604f8201527f29000000000000000000000000000000000000000000000000000000000000006059820152605a0190565b7f5472616e73616374696f6e44617461280000000000000000000000000000000081527f416374696f6e5b5d20616374696f6e732c00000000000000000000000000000060108201527f546f6b656e416d6f756e745b5d20696e707574732c000000000000000000000060218201527f466565206665652c00000000000000000000000000000000000000000000000060368201527f4162736f6c757465546f6b656e416d6f756e745b5d2072657175697265644f75603e8201527f74707574732c0000000000000000000000000000000000000000000000000000605e8201527f75696e74323536206e6f6e63650000000000000000000000000000000000000060648201527f2900000000000000000000000000000000000000000000000000000000000000607182015260720190565b60007f5361666545524332303a2000000000000000000000000000000000000000000082528351612b6a81600b8501602088016134a0565b8083017f2072657475726e65642066616c736520696e2000000000000000000000000000600b82015284519150612ba882601e8301602088016134a0565b01601e01949350505050565b60007f5361666545524332303a2000000000000000000000000000000000000000000082528351612bec81600b8501602088016134a0565b8083017f206661696c656420696e20000000000000000000000000000000000000000000600b82015284519150612c2a8260168301602088016134a0565b01601601949350505050565b7f4162736f6c757465546f6b656e416d6f756e742800000000000000000000000081527f6164647265737320746f6b656e2c00000000000000000000000000000000000060148201527f75696e7432353620616d6f756e7400000000000000000000000000000000000060228201527f2900000000000000000000000000000000000000000000000000000000000000603082015260310190565b7f546f6b656e416d6f756e7428000000000000000000000000000000000000000081527f6164647265737320746f6b656e2c000000000000000000000000000000000000600c8201527f75696e7432353620616d6f756e742c0000000000000000000000000000000000601a8201527f75696e743820616d6f756e74547970650000000000000000000000000000000060298201527f29000000000000000000000000000000000000000000000000000000000000006039820152603a0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6000602082526119df60208301846126bc565b606080825284518282018190526000919060809081850190602080820287018401818b01875b84811015612f2a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8403018652815187840181518552612eae86830151613495565b868601526040808301518a828801528291508051612ecc8185613445565b925088820193508d91505b80821015612efc57612eea838551612662565b92508884019350600182019150612ed7565b50508a83015191508581038b870152612f158183612717565b98870198955050509184019150600101612e6a565b505087810382890152612f3d818b6126bc565b965050505050505061024a60408301846126a2565b92835273ffffffffffffffffffffffffffffffffffffffff919091166020830152604082015260600190565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526040810183905260808101612fb183613495565b606083015295945050505050565b958652602086019490945260408501929092526060840152608083015260a082015260c00190565b8581526020810185905260a0810160038510612fff57fe5b8460408301528360608301528260808301529695505050505050565b928352602083019190915273ffffffffffffffffffffffffffffffffffffffff16604082015260600190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082526119df6020830184612717565b60208082526011908201527f4f3a20656d707479206e65774f776e6572000000000000000000000000000000604082015260600190565b60208082526012908201527f523a206261642062656e65666963696172790000000000000000000000000000604082015260600190565b6020808252600d908201527f4f3a206f6e6c79206f776e657200000000000000000000000000000000000000604082015260600190565b6020808252600b908201527f53563a2062616420277627000000000000000000000000000000000000000000604082015260600190565b60208082526019908201527f4f3a20657175616c20746f2070656e64696e674f776e65725f00000000000000604082015260600190565b6020808252600e908201527f523a207a65726f20616d6f756e74000000000000000000000000000000000000604082015260600190565b6020808252600d908201527f523a2062616420616d6f756e7400000000000000000000000000000000000000604082015260600190565b6020808252600d908201527f53563a20626164206e6f6e636500000000000000000000000000000000000000604082015260600190565b60208082526012908201527f4f3a20657175616c20746f206f776e65725f0000000000000000000000000000604082015260600190565b60208082526015908201527f4f3a206f6e6c792070656e64696e67206f776e65720000000000000000000000604082015260600190565b60208082526012908201527f523a2062616420616d6f756e7420747970650000000000000000000000000000604082015260600190565b6020808252600b908201527f53563a2062616420277327000000000000000000000000000000000000000000604082015260600190565b60208082526022908201527f455448207472616e7366657220746f2062656e6566696369617279206661696c60408201527f6564000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f53563a20626164207369676e6174757265000000000000000000000000000000604082015260600190565b6020808252600a908201527f523a206261642066656500000000000000000000000000000000000000000000604082015260600190565b6020808252600f908201527f523a206d756c206f766572666c6f770000000000000000000000000000000000604082015260600190565b6020808252601b908201527f455448207472616e7366657220746f20436f7265206661696c65640000000000604082015260600190565b90815260200190565b60405181810167ffffffffffffffff8111828210171561346d57600080fd5b604052919050565b600067ffffffffffffffff82111561348b578081fd5b5060209081020190565b806003811061044057fe5b60005b838110156134bb5781810151838201526020016134a3565b838111156113ee5750506000910152565b73ffffffffffffffffffffffffffffffffffffffff811681146134ee57600080fd5b50565b600381106134ee57600080fdfea2646970667358221220d90bfeb4a591f165d95cc8b854cf588cdd46dd6a1c6bd47ad13c6ffd82cd416864736f6c634300060b0033000000000000000000000000d291328a6c202c5b18dcb24f279f69de1e065f70
Deployed Bytecode
0x6080604052600436106100c75760003560e01c80638da5cb5b11610074578063e6096b4d1161004e578063e6096b4d146101e3578063e89db67114610203578063f2f4eb2614610223576100c7565b80638da5cb5b1461018c578063a4592161146101ae578063e30c3978146101ce576100c7565b8063710bf322116100a5578063710bf3221461014257806379ba5097146101645780638042c01f14610179576100c7565b80631b277241146100cc5780636b72b8cf146100f557806370ae92d214610115575b600080fd5b6100df6100da366004612406565b610238565b6040516100ec9190612e31565b60405180910390f35b34801561010157600080fd5b506100df61011036600461249c565b610252565b34801561012157600080fd5b506101356101303660046122f0565b610419565b6040516100ec9190613445565b34801561014e57600080fd5b5061016261015d3660046122f0565b610445565b005b34801561017057600080fd5b506101626105dd565b6100df610187366004612559565b6106ab565b34801561019857600080fd5b506101a16106eb565b6040516100ec9190612d92565b3480156101ba57600080fd5b506101a16101c9366004612559565b610707565b3480156101da57600080fd5b506101a16108e2565b3480156101ef57600080fd5b506100df6101fe36600461249c565b6108fe565b34801561020f57600080fd5b5061016261021e36600461230c565b610a9e565b34801561022f57600080fd5b506101a1610cc5565b60606102478585858533610ce9565b90505b949350505050565b606082818167ffffffffffffffff8111801561026d57600080fd5b506040519080825280602002602001820160405280156102a757816020015b610294611fa0565b81526020019060019003908161028c5790505b509050600080805b8481101561040c576102e28989838181106102c657fe5b9050606002018036038101906102dc919061253e565b88610e84565b92508888828181106102f057fe5b61030692602060609092020190810191506122f0565b73ffffffffffffffffffffffffffffffffffffffff166370a08231886040518263ffffffff1660e01b815260040161033e9190612d92565b60206040518083038186803b15801561035657600080fd5b505afa15801561036a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038e919061264a565b915060405180604001604052808a8a848181106103a757fe5b6103bd92602060609092020190810191506122f0565b73ffffffffffffffffffffffffffffffffffffffff1681526020018385116103e65760006103ea565b8385035b8152508482815181106103f957fe5b60209081029190910101526001016102af565b5091979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020545b919050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461049f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906130e6565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166104ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613078565b60015473ffffffffffffffffffffffffffffffffffffffff82811691161415610541576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613230565b60025473ffffffffffffffffffffffffffffffffffffffff82811691161415610596576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613154565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60025473ffffffffffffffffffffffffffffffffffffffff16331461062e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613267565b600154604051339173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000009081163317909155600280549091169055565b606060006106b98484610707565b90506106c4816110b9565b6106e1846000015185602001518660400151876060015185610ce9565b9150505b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b600080600080610716856110e6565b9194509250905060007f19000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000007fb59f99ca1a30c448b08d3e1d738b3356fee38ca1cd36d6e7a4bc9bad53c50c0a61078b8a6111ed565b60405160200161079e9493929190612761565b6040516020818303038152906040528051906020012090506000600182868686604051600081526020016040526040516107db9493929190613047565b6020604051602081039080840390855afa1580156107fd573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116610875576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613369565b608088015173ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054146108d7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906131f9565b979650505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff1690565b606082818167ffffffffffffffff8111801561091957600080fd5b5060405190808252806020026020018201604052801561095357816020015b610940611fa0565b8152602001906001900390816109385790505b509050600080805b8481101561040c576109728989838181106102c657fe5b925088888281811061098057fe5b61099692602060609092020190810191506122f0565b73ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e88306040518363ffffffff1660e01b81526004016109d0929190612db3565b60206040518083038186803b1580156109e857600080fd5b505afa1580156109fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a20919061264a565b915060405180604001604052808a8a84818110610a3957fe5b610a4f92602060609092020190810191506122f0565b73ffffffffffffffffffffffffffffffffffffffff168152602001838511610a78576000610a7c565b8385035b815250848281518110610a8b57fe5b602090810291909101015260010161095b565b60015473ffffffffffffffffffffffffffffffffffffffff163314610aef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906130e6565b73ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1415610bdb576040805160008082526020820190925273ffffffffffffffffffffffffffffffffffffffff8316904790604051610b5891906127a3565b60006040518083038185875af1925050503d8060008114610b95576040519150601f19603f3d011682016040523d82523d6000602084013e610b9a565b606091505b5050905080610bd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906130af565b50610cc1565b610cc1818373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c189190612d92565b60206040518083038186803b158015610c3057600080fd5b505afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c68919061264a565b60408051808201909152600181527f5200000000000000000000000000000000000000000000000000000000000000602082015273ffffffffffffffffffffffffffffffffffffffff861692919063ffffffff61133616565b5050565b7f000000000000000000000000d291328a6c202c5b18dcb24f279f69de1e065f7090565b606060005a9050610cfb8686856113f4565b6060610d0785886117fa565b905060607f000000000000000000000000d291328a6c202c5b18dcb24f279f69de1e065f7073ffffffffffffffffffffffffffffffffffffffff1663695f72198a84886040518463ffffffff1660e01b8152600401610d6893929190612e44565b600060405180830381600087803b158015610d8257600080fd5b505af1158015610d96573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610ddc9190810190612344565b90506000601036025a8561520801030190506d4946c0e9f43f4dee607b0ef1fa1c73ffffffffffffffffffffffffffffffffffffffff16636366b93661a0aa8361374a0181610e2757fe5b046040518263ffffffff1660e01b8152600401610e449190613445565b600060405180830381600087803b158015610e5e57600080fd5b505af1158015610e72573d6000803e3d6000fd5b50939c9b505050505050505050505050565b81516040830151602084015160009291906001826002811115610ea357fe5b1480610eba57506002826002811115610eb857fe5b145b610ef0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061329e565b6001826002811115610efe57fe5b14156110af57670de0b6b3a7640000811115610f46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906131c2565b670de0b6b3a7640000811415611002576040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416906370a0823190610fa8908890600401612d92565b60206040518083038186803b158015610fc057600080fd5b505afa158015610fd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff8919061264a565b93505050506106e5565b670de0b6b3a764000061109d8473ffffffffffffffffffffffffffffffffffffffff166370a08231886040518263ffffffff1660e01b81526004016110479190612d92565b60206040518083038186803b15801561105f57600080fd5b505afa158015611073573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611097919061264a565b8361198b565b816110a457fe5b0493505050506106e5565b92506106e5915050565b73ffffffffffffffffffffffffffffffffffffffff16600090815260208190526040902080546001019055565b60008060008351604114611126576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049690613369565b50505060208101516040820151606083015160001a91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115611197576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906132d5565b8260ff16601b141580156111af57508260ff16601c14155b156111e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061311d565b9193909250565b60006040516020016111fe906129ff565b60405160208183030381529060405260405160200161121c90612c36565b60405160208183030381529060405260405160200161123a90612918565b6040516020818303038152906040526040516020016112589061287d565b60405160208183030381529060405260405160200161127690612cd1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526112b5959493929160200161280f565b604051602081830303815290604052805190602001206112d883600001516119e6565b6112e58460200151611b74565b6112f28560400151611c70565b6112ff8660600151611cb3565b866080015160405160200161131996959493929190612fbf565b604051602081830303815290604052805190602001209050919050565b6113ee8463a9059cbb60e01b8585604051602401611355929190612e0b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060400160405280600881526020017f7472616e7366657200000000000000000000000000000000000000000000000081525084611d96565b50505050565b8251825160009182918291901561149857602086015173ffffffffffffffffffffffffffffffffffffffff16611456576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906130af565b8551662386f26fc100001015611498576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906133a0565b60005b81811015611630578781815181106114af57fe5b60200260200101516000015194506114da8882815181106114cc57fe5b602002602001015187610e84565b935060008411611516576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061318b565b670de0b6b3a764000061152d85896000015161198b565b8161153457fe5b04925082156115a5576115a5868860200151856040518060400160405280600481526020017f525b315d000000000000000000000000000000000000000000000000000000008152508973ffffffffffffffffffffffffffffffffffffffff16611edf90949392919063ffffffff16565b60408051808201909152600481527f525b325d0000000000000000000000000000000000000000000000000000000060208201526116289073ffffffffffffffffffffffffffffffffffffffff87169088907f000000000000000000000000d291328a6c202c5b18dcb24f279f69de1e065f70908789039063ffffffff611edf16565b60010161149b565b5034156117f157670de0b6b3a764000061164e34886000015161198b565b8161165557fe5b0491508115611718576020868101516040805160008082529381019182905273ffffffffffffffffffffffffffffffffffffffff90921691859161169991906127a3565b60006040518083038185875af1925050503d80600081146116d6576040519150601f19603f3d011682016040523d82523d6000602084013e6116db565b606091505b5050905080611716576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061330c565b505b604080516000808252602082019092527f000000000000000000000000d291328a6c202c5b18dcb24f279f69de1e065f7073ffffffffffffffffffffffffffffffffffffffff1690348590039060405161177291906127a3565b60006040518083038185875af1925050503d80600081146117af576040519150601f19603f3d011682016040523d82523d6000602084013e6117b4565b606091505b50509050806117ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969061340e565b505b50505050505050565b6060600080341161180c57600061180f565b60015b60ff16905060608184518651010167ffffffffffffffff8111801561183357600080fd5b5060405190808252806020026020018201604052801561186d57816020015b61185a611fa0565b8152602001906001900390816118525790505b50905060005b85518110156118af5785818151811061188857fe5b602002602001015182828151811061189c57fe5b6020908102919091010152600101611873565b5060005b84518110156119215760405180604001604052808683815181106118d357fe5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff168152602001600081525082828851018151811061190e57fe5b60209081029190910101526001016118b3565b5081156106e157604051806040016040528073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff16815260200160008152508185518751018151811061197857fe5b6020026020010181905250949350505050565b60008261199a575060006106e5565b828202828482816119a757fe5b04146119df576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610496906133d7565b9392505050565b604080516000808252602082019092528251825b81811015611b645782604051602001611a1290612918565b604051602081830303815290604052604051602001611a3090612cd1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611a6c92916020016127e1565b60405160208183030381529060405280519060200120868381518110611a8e57fe5b602002602001015160000151878481518110611aa657fe5b602002602001015160200151611ad2898681518110611ac157fe5b602002602001015160400151611b74565b898681518110611ade57fe5b60200260200101516060015180519060200120604051602001611b05959493929190612fe7565b60405160208183030381529060405280519060200120604051602001611b2c9291906127bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905292506001016119fa565b5050805160209091012092915050565b604080516000808252602082019092528251825b81811015611b645782604051602001611ba090612cd1565b60405160208183030381529060405280519060200120868381518110611bc257fe5b602002602001015160000151878481518110611bda57fe5b602002602001015160200151888581518110611bf257fe5b602002602001015160400151604051602001611c119493929190612f7e565b60405160208183030381529060405280519060200120604051602001611c389291906127bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529250600101611b88565b6000604051602001611c819061287d565b60405160208183030381529060405280519060200120826000015183602001516040516020016113199392919061301b565b604080516000808252602082019092528251825b81811015611b645782604051602001611cdf90612c36565b60405160208183030381529060405280519060200120868381518110611d0157fe5b602002602001015160000151878481518110611d1957fe5b602002602001015160200151604051602001611d3793929190612f52565b60405160208183030381529060405280519060200120604051602001611d5e9291906127bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529250600101611cc7565b600060608573ffffffffffffffffffffffffffffffffffffffff1685604051611dbf91906127a3565b6000604051808303816000865af19150503d8060008114611dfc576040519150601f19603f3d011682016040523d82523d6000602084013e611e01565b606091505b5091509150818484604051602001611e1a929190612bb4565b60405160208183030381529060405290611e61576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969190613065565b50805115611ed75780806020019051810190611e7d919061251e565b8484604051602001611e90929190612b32565b604051602081830303815290604052906117f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104969190613065565b505050505050565b611f99856323b872dd60e01b868686604051602401611f0093929190612dda565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518060400160405280600c81526020017f7472616e7366657246726f6d000000000000000000000000000000000000000081525084611d96565b5050505050565b604080518082019091526000808252602082015290565b80356106e5816134cc565b80516106e5816134cc565b600082601f830112611fdd578081fd5b8135611ff0611feb82613475565b61344e565b818152915060208083019084810160408085028701830188101561201357600080fd5b6000805b8681101561205c5782848b03121561202d578182fd5b6120368361344e565b6120408b86611fb7565b8152848601358682015286529484019492820192600101612017565b5050505050505092915050565b600082601f830112612079578081fd5b8135612087611feb82613475565b818152915060208083019084810160005b8481101561216357813587016080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838c030112156120d757600080fd5b6120e08161344e565b8583013581526040808401356120f5816134f1565b8288015260608481013567ffffffffffffffff8082111561211557600080fd5b6121238f8b848a010161216e565b848601528587013593508084111561213a57600080fd5b505061214a8d89848801016121e2565b9083015250865250509282019290820190600101612098565b505050505092915050565b600082601f83011261217e578081fd5b813561218c611feb82613475565b81815291506020808301908481016060808502870183018810156121af57600080fd5b60005b858110156121d6576121c489846122a3565b855293830193918101916001016121b2565b50505050505092915050565b600082601f8301126121f2578081fd5b813567ffffffffffffffff811115612208578182fd5b61223960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161344e565b915080825283602082850101111561225057600080fd5b8060208401602084013760009082016020015292915050565b60006040828403121561227a578081fd5b612284604061344e565b9050813581526020820135612298816134cc565b602082015292915050565b6000606082840312156122b4578081fd5b6122be606061344e565b905081356122cb816134cc565b81526020828101359082015260408201356122e5816134f1565b604082015292915050565b600060208284031215612301578081fd5b81356119df816134cc565b6000806040838503121561231e578081fd5b8235612329816134cc565b91506020830135612339816134cc565b809150509250929050565b60006020808385031215612356578182fd5b825167ffffffffffffffff81111561236c578283fd5b80840185601f82011261237d578384fd5b8051915061238d611feb83613475565b828152838101908285016040808602850187018a10156123ab578788fd5b8794505b858510156123f85780828b0312156123c5578788fd5b6123ce8161344e565b6123d88b84611fc2565b8152828801518882015284526001949094019392860192908101906123af565b509098975050505050505050565b60008060008060a0858703121561241b578182fd5b843567ffffffffffffffff80821115612432578384fd5b61243e88838901612069565b95506020870135915080821115612453578384fd5b61245f8883890161216e565b945061246e8860408901612269565b93506080870135915080821115612483578283fd5b5061249087828801611fcd565b91505092959194509250565b6000806000604084860312156124b0578081fd5b833567ffffffffffffffff808211156124c7578283fd5b81860187601f8201126124d8578384fd5b80359250818311156124e8578384fd5b8760206060850283010111156124fc578384fd5b6020908101955091935050840135612513816134cc565b809150509250925092565b60006020828403121561252f578081fd5b815180151581146119df578182fd5b60006060828403121561254f578081fd5b6119df83836122a3565b6000806040838503121561256b578182fd5b823567ffffffffffffffff80821115612582578384fd5b81850160c08188031215612594578485fd5b61259e60a061344e565b92508035828111156125ae578586fd5b6125ba88828401612069565b8452506020810135828111156125ce578586fd5b6125da8882840161216e565b6020850152506125ed8760408301612269565b6040840152608081013582811115612603578586fd5b61260f88828401611fcd565b60608501525060a00135608083015290925060208401359080821115612633578283fd5b50612640858286016121e2565b9150509250929050565b60006020828403121561265b578081fd5b5051919050565b600073ffffffffffffffffffffffffffffffffffffffff8251168352602082015160208401526126956040830151613495565b6040840152505060600190565b73ffffffffffffffffffffffffffffffffffffffff169052565b6000815180845260208085019450808401835b8381101561270c578151805173ffffffffffffffffffffffffffffffffffffffff16885283015183880152604090960195908201906001016126cf565b509495945050505050565b6000815180845261272f8160208601602086016134a0565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fff0000000000000000000000000000000000000000000000000000000000000094851681529290931660018301526002820152602281019190915260420190565b600082516127b58184602087016134a0565b9190910192915050565b600083516127d18184602088016134a0565b9190910191825250602001919050565b600083516127f38184602088016134a0565b83519083016128068282602088016134a0565b01949350505050565b60008651612821818460208b016134a0565b8651908301612834828260208b016134a0565b8651918101612847838260208b016134a0565b86519201905061285b8282602089016134a0565b845191810161286e8382602089016134a0565b90910198975050505050505050565b7f466565280000000000000000000000000000000000000000000000000000000081527f75696e743235362073686172652c00000000000000000000000000000000000060048201527f616464726573732062656e65666963696172790000000000000000000000000060128201527f2900000000000000000000000000000000000000000000000000000000000000602582015260260190565b7f416374696f6e280000000000000000000000000000000000000000000000000081527f627974657333322070726f746f636f6c416461707465724e616d652c0000000060078201527f75696e743820616374696f6e547970652c00000000000000000000000000000060238201527f546f6b656e416d6f756e745b5d20746f6b656e416d6f756e74732c000000000060348201527f6279746573206461746100000000000000000000000000000000000000000000604f8201527f29000000000000000000000000000000000000000000000000000000000000006059820152605a0190565b7f5472616e73616374696f6e44617461280000000000000000000000000000000081527f416374696f6e5b5d20616374696f6e732c00000000000000000000000000000060108201527f546f6b656e416d6f756e745b5d20696e707574732c000000000000000000000060218201527f466565206665652c00000000000000000000000000000000000000000000000060368201527f4162736f6c757465546f6b656e416d6f756e745b5d2072657175697265644f75603e8201527f74707574732c0000000000000000000000000000000000000000000000000000605e8201527f75696e74323536206e6f6e63650000000000000000000000000000000000000060648201527f2900000000000000000000000000000000000000000000000000000000000000607182015260720190565b60007f5361666545524332303a2000000000000000000000000000000000000000000082528351612b6a81600b8501602088016134a0565b8083017f2072657475726e65642066616c736520696e2000000000000000000000000000600b82015284519150612ba882601e8301602088016134a0565b01601e01949350505050565b60007f5361666545524332303a2000000000000000000000000000000000000000000082528351612bec81600b8501602088016134a0565b8083017f206661696c656420696e20000000000000000000000000000000000000000000600b82015284519150612c2a8260168301602088016134a0565b01601601949350505050565b7f4162736f6c757465546f6b656e416d6f756e742800000000000000000000000081527f6164647265737320746f6b656e2c00000000000000000000000000000000000060148201527f75696e7432353620616d6f756e7400000000000000000000000000000000000060228201527f2900000000000000000000000000000000000000000000000000000000000000603082015260310190565b7f546f6b656e416d6f756e7428000000000000000000000000000000000000000081527f6164647265737320746f6b656e2c000000000000000000000000000000000000600c8201527f75696e7432353620616d6f756e742c0000000000000000000000000000000000601a8201527f75696e743820616d6f756e74547970650000000000000000000000000000000060298201527f29000000000000000000000000000000000000000000000000000000000000006039820152603a0190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff92831681529116602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6000602082526119df60208301846126bc565b606080825284518282018190526000919060809081850190602080820287018401818b01875b84811015612f2a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8403018652815187840181518552612eae86830151613495565b868601526040808301518a828801528291508051612ecc8185613445565b925088820193508d91505b80821015612efc57612eea838551612662565b92508884019350600182019150612ed7565b50508a83015191508581038b870152612f158183612717565b98870198955050509184019150600101612e6a565b505087810382890152612f3d818b6126bc565b965050505050505061024a60408301846126a2565b92835273ffffffffffffffffffffffffffffffffffffffff919091166020830152604082015260600190565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526040810183905260808101612fb183613495565b606083015295945050505050565b958652602086019490945260408501929092526060840152608083015260a082015260c00190565b8581526020810185905260a0810160038510612fff57fe5b8460408301528360608301528260808301529695505050505050565b928352602083019190915273ffffffffffffffffffffffffffffffffffffffff16604082015260600190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082526119df6020830184612717565b60208082526011908201527f4f3a20656d707479206e65774f776e6572000000000000000000000000000000604082015260600190565b60208082526012908201527f523a206261642062656e65666963696172790000000000000000000000000000604082015260600190565b6020808252600d908201527f4f3a206f6e6c79206f776e657200000000000000000000000000000000000000604082015260600190565b6020808252600b908201527f53563a2062616420277627000000000000000000000000000000000000000000604082015260600190565b60208082526019908201527f4f3a20657175616c20746f2070656e64696e674f776e65725f00000000000000604082015260600190565b6020808252600e908201527f523a207a65726f20616d6f756e74000000000000000000000000000000000000604082015260600190565b6020808252600d908201527f523a2062616420616d6f756e7400000000000000000000000000000000000000604082015260600190565b6020808252600d908201527f53563a20626164206e6f6e636500000000000000000000000000000000000000604082015260600190565b60208082526012908201527f4f3a20657175616c20746f206f776e65725f0000000000000000000000000000604082015260600190565b60208082526015908201527f4f3a206f6e6c792070656e64696e67206f776e65720000000000000000000000604082015260600190565b60208082526012908201527f523a2062616420616d6f756e7420747970650000000000000000000000000000604082015260600190565b6020808252600b908201527f53563a2062616420277327000000000000000000000000000000000000000000604082015260600190565b60208082526022908201527f455448207472616e7366657220746f2062656e6566696369617279206661696c60408201527f6564000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526011908201527f53563a20626164207369676e6174757265000000000000000000000000000000604082015260600190565b6020808252600a908201527f523a206261642066656500000000000000000000000000000000000000000000604082015260600190565b6020808252600f908201527f523a206d756c206f766572666c6f770000000000000000000000000000000000604082015260600190565b6020808252601b908201527f455448207472616e7366657220746f20436f7265206661696c65640000000000604082015260600190565b90815260200190565b60405181810167ffffffffffffffff8111828210171561346d57600080fd5b604052919050565b600067ffffffffffffffff82111561348b578081fd5b5060209081020190565b806003811061044057fe5b60005b838110156134bb5781810151838201526020016134a3565b838111156113ee5750506000910152565b73ffffffffffffffffffffffffffffffffffffffff811681146134ee57600080fd5b50565b600381106134ee57600080fdfea2646970667358221220d90bfeb4a591f165d95cc8b854cf588cdd46dd6a1c6bd47ad13c6ffd82cd416864736f6c634300060b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d291328a6c202c5b18dcb24f279f69de1e065f70
-----Decoded View---------------
Arg [0] : core (address): 0xD291328a6c202c5B18dCB24f279f69dE1E065f70
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d291328a6c202c5b18dcb24f279f69de1e065f70
Deployed Bytecode Sourcemap
1245:8639:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4447:419;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3024:769;;;;;;;;;;-1:-1:-1;3024:769:6;;;;;:::i;:::-;;:::i;3398:145:7:-;;;;;;;;;;-1:-1:-1;3398:145:7;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1547:298:2:-;;;;;;;;;;-1:-1:-1;1547:298:2;;;;;:::i;:::-;;:::i;:::-;;1983:174;;;;;;;;;;;;;:::i;3976:465:6:-;;;;;;:::i;:::-;;:::i;2217:79:2:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3662:683:7:-;;;;;;;;;;-1:-1:-1;3662:683:7;;;;;:::i;:::-;;:::i;2364:93:2:-;;;;;;;;;;;;;:::i;2226:792:6:-;;;;;;;;;;-1:-1:-1;2226:792:6;;;;;:::i;:::-;;:::i;1786:434::-;;;;;;;;;;-1:-1:-1;1786:434:6;;;;;:::i;:::-;;:::i;3865:105::-;;;;;;;;;;;;;:::i;4447:419::-;4673:28;4724:135;4752:7;4773:6;4793:3;4810:15;4839:10;4724:14;:135::i;:::-;4717:142;;4447:419;;;;;;;:::o;3024:769::-;3170:28;3231:6;3170:28;3231:6;3302:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;3254:81:6;-1:-1:-1;3345:16:6;;;3397:356;3421:6;3417:1;:10;3397:356;;;3459:37;3477:6;;3484:1;3477:9;;;;;;;;;;;;3459:37;;;;;;;;;;:::i;:::-;3488:7;3459:17;:37::i;:::-;3448:48;;3526:6;;3533:1;3526:9;;;;;;;:15;;;:9;;;;;:15;;;;-1:-1:-1;3526:15:6;:::i;:::-;3520:32;;;3553:7;3520:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3510:51;;3598:144;;;;;;;;3643:6;;3650:1;3643:9;;;;;;;:15;;;:9;;;;;:15;;;;-1:-1:-1;3643:15:6;:::i;:::-;3598:144;;;;;;3695:7;3684:8;:18;:43;;3726:1;3684:43;;;3716:7;3705:8;:18;3684:43;3598:144;;;3576:16;3593:1;3576:19;;;;;;;;;;;;;;;;;:166;3429:3;;3397:356;;;-1:-1:-1;3770:16:6;;3024:769;-1:-1:-1;;;;;;;3024:769:6:o;3398:145:7:-;3521:15;;;3491:7;3521:15;;;;;;;;;;;3398:145;;;;:::o;1547:298:2:-;892:6;;;;878:10;:20;870:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;1628:22:::1;::::0;::::1;1620:52;;;;;;;;;;;;:::i;:::-;1702:6;::::0;::::1;1690:18:::0;;::::1;1702:6:::0;::::1;1690:18;;1682:49;;;;;;;;;;;;:::i;:::-;1761:13;::::0;::::1;1749:25:::0;;::::1;1761:13:::0;::::1;1749:25;;1741:63;;;;;;;;;;;;:::i;:::-;1814:13;:24:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;1547:298::o;1983:174::-;998:13;;;;984:10;:27;976:61;;;;;;;;;;;;:::i;:::-;2072:6:::1;::::0;2051:40:::1;::::0;2080:10:::1;::::0;2051:40:::1;2072:6;::::0;2051:40:::1;::::0;2072:6:::1;::::0;2051:40:::1;2101:6;:19:::0;;;;;::::1;2110:10;2101:19;::::0;;;2137:13:::1;2130:20:::0;;;;::::1;::::0;;1983:174::o;3976:465:6:-;4123:28;4167:23;4193:40;4217:4;4223:9;4193:23;:40::i;:::-;4167:66;;4244:20;4256:7;4244:11;:20::i;:::-;4282:152;4310:4;:12;;;4336:4;:11;;;4361:4;:8;;;4383:4;:20;;;4417:7;4282:14;:152::i;:::-;4275:159;;;3976:465;;;;;:::o;2217:79:2:-;2283:6;;;;2217:79;:::o;3662:683:7:-;3815:15;3847:7;3856:9;3867;3880:25;3895:9;3880:14;:25::i;:::-;3846:59;;-1:-1:-1;3846:59:7;-1:-1:-1;3846:59:7;-1:-1:-1;3916:18:7;3994:12;4024;4054:16;4088:10;4093:4;4088;:10::i;:::-;3960:152;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3937:185;;;;;;3916:206;;4133:14;4150:30;4160:10;4172:1;4175;4178;4150:30;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4150:30:7;;;;;;-1:-1:-1;;4199:20:7;;;4191:50;;;;;;;;;;;;:::i;:::-;4277:10;;;;4259:14;;;:6;:14;;;;;;;;;;;:28;4251:54;;;;;;;;;;;;:::i;:::-;4331:6;3662:683;-1:-1:-1;;;;;;;3662:683:7:o;2364:93:2:-;2437:13;;;;2364:93;:::o;2226:792:6:-;2374:28;2435:6;2374:28;2435:6;2508:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;2458:83:6;-1:-1:-1;2551:16:6;;;2603:373;2627:6;2623:1;:10;2603:373;;;2665:37;2683:6;;2690:1;2683:9;;;;;;2665:37;2654:48;;2732:6;;2739:1;2732:9;;;;;;;:15;;;:9;;;;;:15;;;;-1:-1:-1;2732:15:6;:::i;:::-;2726:32;;;2759:7;2776:4;2726:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2716:66;;2821:144;;;;;;;;2866:6;;2873:1;2866:9;;;;;;;:15;;;:9;;;;;:15;;;;-1:-1:-1;2866:15:6;:::i;:::-;2821:144;;;;;;2918:7;2907:8;:18;:43;;2949:1;2907:43;;;2939:7;2928:8;:18;2907:43;2821:144;;;2797:18;2816:1;2797:21;;;;;;;;;;;;;;;;;:168;2635:3;;2603:373;;1786:434;892:6:2;;;;878:10;:20;870:46;;;;;;;;;;;;:::i;:::-;1931:12:6::1;::::0;::::1;1497:42;1931:12;1927:287;;;2025:12;::::0;;1960::::1;2025::::0;;;::::1;::::0;::::1;::::0;;;1978:16:::1;::::0;::::1;::::0;2002:21:::1;::::0;1978:60:::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1959:79;;;2060:7;2052:38;;;;;;;;;;;;:::i;:::-;1927:287;;;;2121:82;2147:11;2166:5;2160:22;;;2191:4;2160:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2121:82;::::0;;;;::::1;::::0;;;::::1;::::0;;::::1;;::::0;::::1;::::0;:25:::1;::::0;::::1;::::0;:82;;::::1;:25;:82;:::i;:::-;1786:434:::0;;:::o;3865:105::-;3958:5;3865:105;:::o;4872:1150::-;5117:28;5213:11;5227:9;5213:23;;5337:36;5352:6;5360:3;5365:7;5337:14;:36::i;:::-;5383:44;5430:38;5444:15;5461:6;5430:13;:38::i;:::-;5383:85;;5577:42;5635:5;5622:35;;;5671:7;5692:15;5721:7;5622:116;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5577:161;-1:-1:-1;5798:16:6;5843:2;5848:8;5843:20;5831:9;5825:3;5817:5;:11;:23;:46;5798:65;;1417:42;5873:17;;;5912:5;5892:8;5903:5;5892:16;5891:26;;;;;;5873:45;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6002:13:6;;4872:1150;-1:-1:-1;;;;;;;;;;;;4872:1150:6:o;7767:829::-;7951:17;;8002:22;;;;8051:18;;;;7912:7;;7951:17;8002:22;8115:19;8101:10;:33;;;;;;;;;:70;;;-1:-1:-1;8152:19:6;8138:10;:33;;;;;;;;;8101:70;8080:135;;;;;;;;;;;;:::i;:::-;8244:19;8230:10;:33;;;;;;;;;8226:364;;;1583:4;8287:6;:19;;8279:45;;;;;;;;;;;;:::i;:::-;1583:4;8342:6;:19;8338:198;;;8388:31;;;;;:22;;;;;;:31;;8411:7;;8388:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8381:38;;;;;;;8338:198;1583:4;8465:44;8475:5;8469:22;;;8492:7;8469:31;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8502:6;8465:3;:44::i;:::-;:56;;;;;;8458:63;;;;;;;8226:364;8573:6;-1:-1:-1;8566:13:6;;-1:-1:-1;;8566:13:6;3549:107:7;3632:15;;:6;:15;;;;;;;;;;:17;;;;;;3549:107::o;7337:1766::-;7446:7;7455:9;7466;7499;:16;7519:2;7499:22;7491:52;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;7659:2:7;7644:18;;7638:25;7734:2;7719:18;;7713:25;7846:2;7831:18;;7825:25;7822:1;7817:34;;7638:25;8876:66;8863:79;;8859:131;;;8958:21;;;;;;;;;;:::i;8859:131::-;9004:1;:7;;9009:2;9004:7;;:18;;;;;9015:1;:7;;9020:2;9015:7;;9004:18;9000:70;;;9038:21;;;;;;;;;;:::i;9000:70::-;7337:1766;;;;;:::o;4405:407::-;4509:7;2065:220;;;;;;;:::i;:::-;;;;;;;;;;;;;2352:119;;;;;;;:::i;:::-;;;;;;;;;;;;;2523:184;;;;;;;:::i;:::-;;;;;;;;;;;;;2756:108;;;;;;;:::i;:::-;;;;;;;;;;;;;2922:140;;;;;;;:::i;:::-;;;;;;;;;;;;;;;1338:210;;;;;;2922:140;1338:210;;:::i;:::-;;;;;;;;;;;;;1319:235;;;;;;4624:18;4629:4;:12;;;4624:4;:18::i;:::-;4660:17;4665:4;:11;;;4660:4;:17::i;:::-;4695:14;4700:4;:8;;;4695:4;:14::i;:::-;4727:26;4732:4;:20;;;4727:4;:26::i;:::-;4771:4;:10;;;4562:233;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4539:266;;;;;;4532:273;;4405:407;;;:::o;1276:389:11:-;1431:227;1463:5;1522:23;;;1563:2;1583:5;1482:120;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1431:227;;;;;;;;;;;;;;;;;1640:8;1431:18;:227::i;:::-;1276:389;;;;:::o;6028:1733:6:-;6274:13;;6302:9;;6175:13;;;;;;6274;6302;6298:163;;6339:15;;;;:29;;6331:60;;;;;;;;;;;;:::i;:::-;6413:9;;1639:4;-1:-1:-1;6413:22:6;6405:45;;;;;;;;;;;;:::i;:::-;6476:9;6471:693;6495:6;6491:1;:10;6471:693;;;6530:6;6537:1;6530:9;;;;;;;;;;;;;;:15;;;6522:23;;6576:37;6594:6;6601:1;6594:9;;;;;;;;;;;;;;6605:7;6576:17;:37::i;:::-;6559:54;;6652:1;6635:14;:18;6627:45;;;;;;;;;;;;:::i;:::-;1583:4;6699:30;6703:14;6719:3;:9;;;6699:3;:30::i;:::-;:42;;;;;;;-1:-1:-1;6760:13:6;;6756:224;;6793:172;6844:7;6873:3;:15;;;6910:9;6793:172;;;;;;;;;;;;;;;;;6799:5;6793:29;;;;:172;;;;;;;:::i;:::-;6994:159;;;;;;;;;;;;;;;;;;;:29;;;;7041:7;;7066:5;;7089:26;;;;6994:159;:29;:159;:::i;:::-;6503:3;;6471:693;;;-1:-1:-1;7178:9:6;:13;7174:581;;1583:4;7219:25;7223:9;7234:3;:9;;;7219:3;:25::i;:::-;:37;;;;;;;-1:-1:-1;7275:13:6;;7271:262;;7394:15;;;;;7433:12;;;7376;7433;;;;;;;;;;7394:20;;;;;7422:9;;7394:52;;7433:12;7394:52;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7375:71;;;7472:7;7464:54;;;;;;;;;;;;:::i;:::-;7271:262;;7670:12;;;7611;7670;;;;;;;;;7629:5;:10;;;7647:9;:21;;;;7629:54;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7610:73;;;7705:7;7697:47;;;;;;;;;;;;:::i;:::-;7174:581;;6028:1733;;;;;;;:::o;8602:1001::-;8769:28;8813:16;8844:1;8832:9;:13;:21;;8852:1;8832:21;;;8848:1;8832:21;8813:40;;;;8863:44;8990:8;8974:6;:13;8949:15;:22;:38;:49;8910:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;8863:145:6;-1:-1:-1;9024:9:6;9019:117;9043:15;:22;9039:1;:26;9019:117;;;9107:15;9123:1;9107:18;;;;;;;;;;;;;;9086:15;9102:1;9086:18;;;;;;;;;;;;;;;;;:39;9067:3;;9019:117;;;-1:-1:-1;9151:9:6;9146:217;9170:6;:13;9166:1;:17;9146:217;;;9250:102;;;;;;;;9295:6;9302:1;9295:9;;;;;;;;;;;;;;:15;;;9250:102;;;;;;9336:1;9250:102;;;9204:15;9245:1;9220:15;:22;:26;9204:43;;;;;;;;;;;;;;;;;:148;9185:3;;9146:217;;;-1:-1:-1;9377:12:6;;9373:191;;9463:90;;;;;;;;1497:42;9463:90;;;;;;9537:1;9463:90;;;9405:15;9446:6;:13;9421:15;:22;:38;9405:55;;;;;;;;;;;;;:148;;;;9581:15;8602:1001;-1:-1:-1;;;;8602:1001:6:o;9609:273::-;9713:7;9740:6;9736:45;;-1:-1:-1;9769:1:6;9762:8;;9736:45;9803:5;;;9807:1;9803;:5;:1;9826:5;;;;;:10;9818:38;;;;;;;;;;;;:::i;:::-;9874:1;9609:273;-1:-1:-1;;;9609:273:6:o;4818:745:7:-;4968:12;;;4918:7;4968:12;;;;;;;;;5008:14;;4918:7;5032:485;5056:6;5052:1;:10;5032:485;;;5131:11;2523:184;;;;;;;:::i;:::-;;;;;;;;;;;;;2922:140;;;;;;;:::i;:::-;;;;;;;;;;;;;;;1741:98;;;2922:140;1741:98;;:::i;:::-;;;;;;;;;;;;;1722:123;;;;;;5268:7;5276:1;5268:10;;;;;;;;;;;;;;:30;;;5324:7;5332:1;5324:10;;;;;;;;;;;;;;:21;;;5371:29;5376:7;5384:1;5376:10;;;;;;;;;;;;;;:23;;;5371:4;:29::i;:::-;5436:7;5444:1;5436:10;;;;;;;;;;;;;;:15;;;5426:26;;;;;;5191:283;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5160:332;;;;;;5097:409;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;5064:3:7;;5032:485;;;-1:-1:-1;;5534:22:7;;;;;;;;4818:745;-1:-1:-1;;4818:745:7:o;5569:723::-;5734:12;;;5679:7;5734:12;;;;;;;;;5774:19;;5679:7;5803:438;5827:6;5823:1;:10;5803:438;;;5907:16;2922:140;;;;;;;:::i;:::-;;;;;;;;;;;;;1975:36;;;;;;6055:12;6068:1;6055:15;;;;;;;;;;;;;;:21;;;6102:12;6115:1;6102:15;;;;;;;;;;;;;;:22;;;6150:12;6163:1;6150:15;;;;;;;;;;;;;;:26;;;5972:226;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5941:275;;;;;;5873:357;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;5835:3:7;;5803:438;;6298:275;6389:7;2756:108;;;;;;;:::i;:::-;;;;;;;;;;;;;1892:27;;;;;;6500:3;:9;;;6527:3;:15;;;6442:114;;;;;;;;;;:::i;6579:752::-;6768:12;;;6705:7;6768:12;;;;;;;;;6808:27;;6705:7;6845:427;6869:6;6865:1;:10;6845:427;;;6957:24;2352:119;;;;;;;:::i;:::-;;;;;;;;;;;;;1627:45;;;;;;7122:20;7143:1;7122:23;;;;;;;;;;;;;;:29;;;7177:20;7198:1;7177:23;;;;;;;;;;;;;;:30;;;7030:199;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;6999:248;;;;;;6923:338;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;-1:-1:-1;6877:3:7;;6845:427;;3111:1415:11;3767:12;3781:23;3816:5;3808:19;;3828:4;3808:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3766:67;;;;3864:7;3982:12;4051:8;3909:168;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3843:258;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;4116:17:11;;:21;4112:408;;4216:10;4205:30;;;;;;;;;;;;:::i;:::-;4362:12;4447:8;4281:196;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4180:329;;;;;;;;;;;;;;:::i;4112:408::-;3111:1415;;;;;;:::o;1671:445::-;1852:257;1884:5;1943:27;;;1988:4;2010:2;2030:5;1903:146;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1852:257;;;;;;;;;;;;;;;;;2091:8;1852:18;:257::i;:::-;1671:445;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;:::o;5:130::-;72:20;;97:33;72:20;97:33;:::i;142:134::-;220:13;;238:33;220:13;238:33;:::i;473:818::-;;627:3;620:4;612:6;608:17;604:27;594:2;;-1:-1;;635:12;594:2;682:6;669:20;704:117;719:101;813:6;719:101;:::i;:::-;704:117;:::i;:::-;849:21;;;695:126;-1:-1;893:4;906:14;;;;881:17;;;1007:4;995:17;;;986:27;;;;983:36;-1:-1;980:2;;;1032:1;;1022:12;980:2;1057:1;;1042:243;1067:6;1064:1;1061:13;1042:243;;;1007:4;5412:9;5407:3;5403:19;5399:30;5396:2;;;1057:1;;5432:12;5396:2;5460:20;1007:4;5460:20;:::i;:::-;5563:49;5608:3;5584:22;5563:49;:::i;:::-;5538:75;;5730:22;;;10040:20;5691:16;;;5684:75;1135:87;;1236:14;;;;1264;;;;1089:1;1082:9;1042:243;;;1046:14;;;;;;;587:704;;;;:::o;2201:750::-;;2342:3;2335:4;2327:6;2323:17;2319:27;2309:2;;-1:-1;;2350:12;2309:2;2397:6;2384:20;2419:104;2434:88;2515:6;2434:88;:::i;2419:104::-;2551:21;;;2410:113;-1:-1;2595:4;2608:14;;;;2583:17;;;2703:1;2688:257;2713:6;2710:1;2707:13;2688:257;;;2796:3;2783:17;2587:6;2771:30;6475:4;;6454:19;2771:30;6458:3;6454:19;;6450:30;6447:2;;;2703:1;;6483:12;6447:2;6511:20;6475:4;6511:20;:::i;:::-;2595:4;2771:30;;4412:20;6610:16;6603:75;6814:22;;2771:30;6814:22;5013:20;5038:48;5080:5;5038:48;:::i;:::-;6760:16;;;6753:90;6925:18;;;;6912:32;6964:18;6953:30;;;6950:2;;;2703:1;;6986:12;6950:2;7031:103;7130:3;2595:4;7121:6;2771:30;7106:22;;7031:103;:::i;:::-;6814:22;7017:5;7013:16;7006:129;6475:4;2771:30;7209:18;7196:32;7182:46;;6964:18;7240:6;7237:30;7234:2;;;2703:1;;7270:12;7234:2;;;7315:58;7369:3;2595:4;7360:6;2771:30;7345:22;;7315:58;:::i;:::-;7297:16;;;7290:84;-1:-1;2808:74;;-1:-1;;2896:14;;;;2924;;;;2735:1;2728:9;2688:257;;;2692:14;;;;;2302:649;;;;:::o;3408:794::-;;3554:3;3547:4;3539:6;3535:17;3531:27;3521:2;;-1:-1;;3562:12;3521:2;3609:6;3596:20;3631:109;3646:93;3732:6;3646:93;:::i;3631:109::-;3768:21;;;3622:118;-1:-1;3812:4;3825:14;;;;3800:17;;;3926:4;3914:17;;;3905:27;;;;3902:36;-1:-1;3899:2;;;3951:1;;3941:12;3899:2;3976:1;3961:235;3986:6;3983:1;3980:13;3961:235;;;4066:66;4128:3;4116:10;4066:66;:::i;:::-;4054:79;;4147:14;;;;4175;;;;4008:1;4001:9;3961:235;;;3965:14;;;;;;3514:688;;;;:::o;4483:440::-;;4584:3;4577:4;4569:6;4565:17;4561:27;4551:2;;-1:-1;;4592:12;4551:2;4639:6;4626:20;66692:18;66684:6;66681:30;66678:2;;;-1:-1;;66714:12;66678:2;4661:64;66855:4;66787:9;4577:4;66772:6;66768:17;66764:33;66845:15;4661:64;:::i;:::-;4652:73;;4745:6;4738:5;4731:21;4849:3;66855:4;4840:6;4773;4831:16;;4828:25;4825:2;;;4866:1;;4856:12;4825:2;71411:6;66855:4;4773:6;4769:17;66855:4;4807:5;4803:16;71388:30;71467:1;71449:16;;;66855:4;71449:16;71442:27;4807:5;4544:379;-1:-1;;4544:379::o;7419:471::-;;7529:4;7517:9;7512:3;7508:19;7504:30;7501:2;;;-1:-1;;7537:12;7501:2;7565:20;7529:4;7565:20;:::i;:::-;7556:29;;10053:6;10040:20;7650:16;7643:75;7786:2;7844:9;7840:22;72:20;97:33;124:5;97:33;:::i;:::-;7786:2;7801:16;;7794:75;7805:5;7495:395;-1:-1;;7495:395::o;7922:639::-;;8040:4;8028:9;8023:3;8019:19;8015:30;8012:2;;;-1:-1;;8048:12;8012:2;8076:20;8040:4;8076:20;:::i;:::-;8067:29;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;8154:75;;8292:2;8346:22;;;10040:20;8307:16;;;8300:75;8442:2;8511:22;;5013:20;5038:48;5013:20;5038:48;:::i;:::-;8442:2;8457:16;;8450:90;8461:5;8006:555;-1:-1;;8006:555::o;10251:241::-;;10355:2;10343:9;10334:7;10330:23;10326:32;10323:2;;;-1:-1;;10361:12;10323:2;85:6;72:20;97:33;124:5;97:33;:::i;10499:382::-;;;10628:2;10616:9;10607:7;10603:23;10599:32;10596:2;;;-1:-1;;10634:12;10596:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;10686:63;-1:-1;10786:2;10833:22;;358:20;383:41;358:20;383:41;:::i;:::-;10794:71;;;;10590:291;;;;;:::o;10888:466::-;;11065:2;;11053:9;11044:7;11040:23;11036:32;11033:2;;;-1:-1;;11071:12;11033:2;11122:17;11116:24;11160:18;11152:6;11149:30;11146:2;;;-1:-1;;11182:12;11146:2;11321:6;11310:9;11306:22;1501:3;1494:4;1486:6;1482:17;1478:27;1468:2;;-1:-1;;1509:12;1468:2;1549:6;1543:13;1529:27;;1571:117;1586:101;1680:6;1586:101;:::i;1571:117::-;1716:21;;;1773:14;;;;1748:17;;;1874:4;1862:17;;;1853:27;;;;1850:36;-1:-1;1847:2;;;-1:-1;;1889:12;1847:2;-1:-1;1915:10;;1909:254;1934:6;1931:1;1928:13;1909:254;;;1874:4;5945:9;5940:3;5936:19;5932:30;5929:2;;;-1:-1;;5965:12;5929:2;5993:20;1874:4;5993:20;:::i;:::-;6096:60;6152:3;6128:22;6096:60;:::i;:::-;6071:86;;6285:22;;;10188:13;6235:16;;;6228:86;2002:98;;1956:1;1949:9;;;;;2114:14;;;;2142;;;;1909:254;;;-1:-1;11202:136;;11027:327;-1:-1;;;;;;;;11027:327::o;11361:1248::-;;;;;11702:3;11690:9;11681:7;11677:23;11673:33;11670:2;;;-1:-1;;11709:12;11670:2;11767:17;11754:31;11805:18;;11797:6;11794:30;11791:2;;;-1:-1;;11827:12;11791:2;11857:102;11951:7;11942:6;11931:9;11927:22;11857:102;:::i;:::-;11847:112;;12024:2;12013:9;12009:18;11996:32;11982:46;;11805:18;12040:6;12037:30;12034:2;;;-1:-1;;12070:12;12034:2;12100:107;12199:7;12190:6;12179:9;12175:22;12100:107;:::i;:::-;12090:117;;12262:74;12328:7;12244:2;12308:9;12304:22;12262:74;:::i;:::-;12252:84;;12401:3;12390:9;12386:19;12373:33;12359:47;;11805:18;12418:6;12415:30;12412:2;;;-1:-1;;12448:12;12412:2;;12478:115;12585:7;12576:6;12565:9;12561:22;12478:115;:::i;:::-;12468:125;;;11664:945;;;;;;;:::o;12616:584::-;;;;12803:2;12791:9;12782:7;12778:23;12774:32;12771:2;;;-1:-1;;12809:12;12771:2;12867:17;12854:31;12905:18;;12897:6;12894:30;12891:2;;;-1:-1;;12927:12;12891:2;13059:6;13048:9;13044:22;3149:3;3142:4;3134:6;3130:17;3126:27;3116:2;;-1:-1;;3157:12;3116:2;3200:6;3187:20;3177:30;;12905:18;3219:6;3216:30;3213:2;;;-1:-1;;3249:12;3213:2;3344:3;3293:4;3336;3328:6;3324:17;3285:6;3310:32;;3307:41;3304:2;;;-1:-1;;3351:12;3304:2;3293:4;3281:17;;;;-1:-1;12947:129;;-1:-1;;13152:22;;72:20;97:33;72:20;97:33;:::i;:::-;13121:63;;;;12765:435;;;;;:::o;13207:257::-;;13319:2;13307:9;13298:7;13294:23;13290:32;13287:2;;;-1:-1;;13325:12;13287:2;4291:6;4285:13;72597:5;70206:13;70199:21;72575:5;72572:32;72562:2;;-1:-1;;72608:12;13471:299;;13604:2;13592:9;13583:7;13579:23;13575:32;13572:2;;;-1:-1;;13610:12;13572:2;13672:82;13746:7;13722:22;13672:82;:::i;13777:622::-;;;13940:2;13928:9;13919:7;13915:23;13911:32;13908:2;;;-1:-1;;13946:12;13908:2;14004:17;13991:31;14042:18;;14034:6;14031:30;14028:2;;;-1:-1;;14064:12;14028:2;14163:6;14152:9;14148:22;8719:4;8707:9;8702:3;8698:19;8694:30;8691:2;;;-1:-1;;8727:12;8691:2;8755:20;8770:4;8755:20;:::i;:::-;8746:29;;8841:17;8828:31;14042:18;8871:6;8868:30;8865:2;;;-1:-1;;8901:12;8865:2;8946:98;9040:3;9031:6;9020:9;9016:22;8946:98;:::i;:::-;8928:16;8921:124;;9136:2;9125:9;9121:18;9108:32;14042:18;9152:6;9149:30;9146:2;;;-1:-1;;9182:12;9146:2;9227:103;9326:3;9317:6;9306:9;9302:22;9227:103;:::i;:::-;9136:2;9213:5;9209:16;9202:129;;9424:70;9490:3;13940:2;9470:9;9466:22;9424:70;:::i;:::-;13940:2;9410:5;9406:16;9399:96;9595:3;9584:9;9580:19;9567:33;14042:18;9612:6;9609:30;9606:2;;;-1:-1;;9642:12;9606:2;9687:111;9794:3;9785:6;9774:9;9770:22;9687:111;:::i;:::-;9680:4;9669:16;;9662:137;-1:-1;8770:4;9916:22;10040:20;9595:3;9877:16;;9870:75;9673:5;;-1:-1;9136:2;14230:18;;14217:32;;14258:30;;;14255:2;;;-1:-1;;14291:12;14255:2;;14321:62;14375:7;14366:6;14355:9;14351:22;14321:62;:::i;:::-;14311:72;;;13902:497;;;;;:::o;14406:263::-;;14521:2;14509:9;14500:7;14496:23;14492:32;14489:2;;;-1:-1;;14527:12;14489:2;-1:-1;10188:13;;14483:186;-1:-1;14483:186::o;15265:289::-;;70821:42;37832:16;37826:23;70810:54;15656:3;15649:45;37999:4;37992:5;37988:16;37982:23;37999:4;38063:3;38059:14;19269:37;71278:39;38159:4;38152:5;38148:16;38142:23;71278:39;:::i;:::-;38159:4;38232:14;;20672:63;-1:-1;;15543:4;15534:14;;15403:151::o;15562:137::-;70821:42;70810:54;15649:45;;15643:56::o;16005:986::-;;16309:5;67581:12;68823:6;68818:3;68811:19;68860:4;;68855:3;68851:14;16321:130;;68860:4;16559:5;67029:14;-1:-1;16598:371;16623:6;16620:1;16617:13;16598:371;;;16684:13;;36180:23;;70821:42;70810:54;15649:45;;36342:16;;36336:23;36413:14;;;19269:37;14987:4;14978:14;;;;68346;;;;16645:1;16638:9;16598:371;;;-1:-1;16975:10;;16203:788;-1:-1;;;;;16203:788::o;19597:323::-;;19729:5;67581:12;68823:6;68818:3;68811:19;19812:52;19857:6;68860:4;68855:3;68851:14;68860:4;19838:5;19834:16;19812:52;:::i;:::-;72009:2;71989:14;72005:7;71985:28;19876:39;;;;68860:4;19876:39;;19677:243;-1:-1;;19677:243::o;38619:660::-;70304:66;70293:78;;;19140:56;;70293:78;;;;38922:1;38913:11;;19140:56;39021:11;;;19269:37;39131:12;;;19269:37;;;;39242:12;;;38815:464::o;39286:271::-;;20087:5;67581:12;20198:52;20243:6;20238:3;20231:4;20224:5;20220:16;20198:52;:::i;:::-;20262:16;;;;;39420:137;-1:-1;;39420:137::o;39564:410::-;;20087:5;67581:12;20198:52;20243:6;20238:3;20231:4;20224:5;20220:16;20198:52;:::i;:::-;20262:16;;;;19269:37;;;-1:-1;20231:4;39937:12;;39726:248;-1:-1;39726:248::o;39981:428::-;;20087:5;67581:12;20198:52;20243:6;20238:3;20231:4;20224:5;20220:16;20198:52;:::i;:::-;67581:12;;;20262:16;;20198:52;67581:12;20262:16;20231:4;20220:16;;20198:52;:::i;:::-;20262:16;;40161:248;-1:-1;;;;40161:248::o;40416:899::-;;20087:5;67581:12;20198:52;20243:6;20238:3;20231:4;20224:5;20220:16;20198:52;:::i;:::-;67581:12;;;20262:16;;20198:52;67581:12;20262:16;20231:4;20220:16;;20198:52;:::i;:::-;67581:12;;;20262:16;;20198:52;67581:12;20262:16;20231:4;20220:16;;20198:52;:::i;:::-;67581:12;;;20262:16;;-1:-1;20198:52;67581:12;20262:16;20231:4;20220:16;;20198:52;:::i;:::-;67581:12;;;20262:16;;20198:52;67581:12;20262:16;20231:4;20220:16;;20198:52;:::i;:::-;20262:16;;;;40734:581;-1:-1;;;;;;;;40734:581::o;41322:1182::-;23623:6;23603:27;;25767:16;23588:1;23649:11;;25747:37;29199:21;25803:12;;;29179:42;27816:3;29240:12;;;27796:24;27839:11;;;41814:690::o;42511:1716::-;28160:9;28140:30;;31285;28125:1;28189:11;;31265:51;32730:19;31335:12;;;32710:40;31978:29;32769:12;;;31958:50;29893:12;32027;;;29873:33;27816:3;29925:12;;;27796:24;27839:11;;;43205:1022::o;44234:1983::-;28838:18;28818:39;;25405:19;28802:2;28876:12;;25385:40;26771:23;25444:12;;;26751:44;30933:10;26814:12;;;30913:31;24331:34;30963:11;;;24311:55;24400:8;24386:12;;;24379:30;27459:15;24428:12;;;27439:36;27816:3;27494:12;;;27796:24;27839:11;;;45029:1188::o;46224:970::-;;34417:13;34404:11;34397:34;20087:5;67581:12;20198:52;20243:6;34381:2;34454:3;34450:12;20231:4;20224:5;20220:16;20198:52;:::i;:::-;20271:6;34454:3;20262:16;22938:21;34381:2;20262:16;;22918:42;20087:5;67581:12;20041:52;;20198;20243:6;22979:12;20262:16;22979:12;20231:4;20224:5;20220:16;20198:52;:::i;:::-;20262:16;22979:12;20262:16;;46610:584;-1:-1;;;;46610:584::o;47201:970::-;;34417:13;34404:11;34397:34;20087:5;67581:12;20198:52;20243:6;34381:2;34454:3;34450:12;20231:4;20224:5;20220:16;20198:52;:::i;:::-;20271:6;34454:3;20262:16;33418:13;34381:2;20262:16;;33398:34;20087:5;67581:12;20041:52;;20198;20243:6;33451:12;20262:16;33451:12;20231:4;20224:5;20220:16;20198:52;:::i;:::-;20262:16;33451:12;20262:16;;47587:584;-1:-1;;;;47587:584::o;48178:1182::-;35109:22;35089:43;;35831:16;35073:2;35151:12;;35811:37;30575:16;35867:12;;;30555:37;27816:3;30611:12;;;27796:24;27839:11;;;48670:690::o;49367:1449::-;35474:14;35454:35;;35831:16;35438:2;35508:12;;35811:37;23971:17;35867:12;;;23951:38;21924:18;24008:12;;;21904:39;27816:3;21962:12;;;27796:24;27839:11;;;49960:856::o;50823:222::-;70821:42;70810:54;;;;15649:45;;50950:2;50935:18;;50921:124::o;51313:333::-;70821:42;70810:54;;;15649:45;;70810:54;;51632:2;51617:18;;15649:45;51468:2;51453:18;;51439:207::o;51653:444::-;70821:42;70810:54;;;15649:45;;70810:54;;;;52000:2;51985:18;;15649:45;52083:2;52068:18;;19269:37;;;;51836:2;51821:18;;51807:290::o;52104:333::-;70821:42;70810:54;;;;15649:45;;52423:2;52408:18;;19269:37;52259:2;52244:18;;52230:207::o;52444:518::-;;52695:2;52716:17;52709:47;52770:182;52695:2;52684:9;52680:18;52938:6;52770:182;:::i;52969:1016::-;53390:2;53404:47;;;67581:12;;53375:18;;;68811:19;;;52969:1016;;53390:2;68851:14;;;;;;68860:4;17489:17;;;17480:27;;;;67029:14;;;52969:1016;17641:402;17666:6;17663:1;17660:13;17641:402;;;17718:20;53379:9;17722:4;17718:20;;17713:3;17706:33;17773:6;17767:13;68851:14;36627:3;36623:14;36719:16;36713:23;19276:3;19269:37;71135:39;68860:4;36883:5;36879:16;36873:23;71135:39;:::i;:::-;68860:4;36967:3;36963:14;20364:63;37065:4;;37058:5;37054:16;37048:23;68851:14;37065:4;37095:3;37091:14;37084:38;37137:161;;;18413:5;67581:12;18432:105;18530:6;18525:3;18432:105;:::i;:::-;18425:112;;68860:4;18637:5;67029:14;18649:21;;-1:-1;18682:10;;18676:347;18701:6;18698:1;18695:13;18676:347;;;18789:121;18906:3;18768:6;18762:13;18789:121;:::i;:::-;18782:128;;68860:4;19009:6;68346:14;18917:99;;17688:1;18720;18716:9;18711:14;;18676:347;;;18680:14;;53390:2;37376:5;37372:16;37366:23;37346:43;;37435:3;37429:4;37425:14;53390:2;37413:3;37409:14;37402:38;37455:71;37521:4;37507:12;37455:71;:::i;:::-;18022:14;;;;17787:120;-1:-1;;;68346:14;;;;-1:-1;17688:1;17681:9;17641:402;;;17645:14;;53669:9;53663:4;53659:20;68860:4;53643:9;53639:18;53632:48;53694:182;53871:4;53862:6;53694:182;:::i;:::-;53686:190;;;;;;;;53887:88;37065:4;53960:9;53956:18;53947:6;53887:88;:::i;53992:444::-;19269:37;;;70821:42;70810:54;;;;54339:2;54324:18;;15649:45;54422:2;54407:18;;19269:37;54175:2;54160:18;;54146:290::o;54443:582::-;19269:37;;;70821:42;70810:54;;54832:2;54817:18;;15649:45;54915:2;54900:18;;19269:37;;;54667:3;54652:19;;71278:39;20728:5;71278:39;:::i;:::-;55011:2;55000:9;54996:18;20672:63;54638:387;;;;;;;:::o;55032:780::-;19269:37;;;55464:2;55449:18;;19269:37;;;;55547:2;55532:18;;19269:37;;;;55630:2;55615:18;;19269:37;55713:3;55698:19;;19269:37;55797:3;55782:19;;19269:37;55299:3;55284:19;;55270:542::o;55819:694::-;19269:37;;;56236:2;56221:18;;19269:37;;;56071:3;56056:19;;72110:1;72100:12;;72090:2;;72116:9;72090:2;71135:39;56332:2;56321:9;56317:18;20364:63;19299:5;56415:2;56404:9;56400:18;19269:37;19299:5;56498:3;56487:9;56483:19;19269:37;56042:471;;;;;;;;:::o;56520:444::-;19269:37;;;56867:2;56852:18;;19269:37;;;;70821:42;70810:54;56950:2;56935:18;;15649:45;56703:2;56688:18;;56674:290::o;56971:548::-;19269:37;;;71026:4;71015:16;;;;57339:2;57324:18;;38572:35;57422:2;57407:18;;19269:37;57505:2;57490:18;;19269:37;57178:3;57163:19;;57149:370::o;57526:310::-;;57673:2;57694:17;57687:47;57748:78;57673:2;57662:9;57658:18;57812:6;57748:78;:::i;57843:416::-;58043:2;58057:47;;;22213:2;58028:18;;;68811:19;22249;68851:14;;;22229:40;22288:12;;;58014:245::o;58266:416::-;58466:2;58480:47;;;22539:2;58451:18;;;68811:19;22575:20;68851:14;;;22555:41;22615:12;;;58437:245::o;58689:416::-;58889:2;58903:47;;;23230:2;58874:18;;;68811:19;23266:15;68851:14;;;23246:36;23301:12;;;58860:245::o;59112:416::-;59312:2;59326:47;;;24679:2;59297:18;;;68811:19;24715:13;68851:14;;;24695:34;24748:12;;;59283:245::o;59535:416::-;59735:2;59749:47;;;24999:2;59720:18;;;68811:19;25035:27;68851:14;;;25015:48;25082:12;;;59706:245::o;59958:416::-;60158:2;60172:47;;;26054:2;60143:18;;;68811:19;26090:16;68851:14;;;26070:37;26126:12;;;60129:245::o;60381:416::-;60581:2;60595:47;;;26377:2;60566:18;;;68811:19;26413:15;68851:14;;;26393:36;26448:12;;;60552:245::o;60804:416::-;61004:2;61018:47;;;27065:2;60989:18;;;68811:19;27101:15;68851:14;;;27081:36;27136:12;;;60975:245::o;61227:416::-;61427:2;61441:47;;;28439:2;61412:18;;;68811:19;28475:20;68851:14;;;28455:41;28515:12;;;61398:245::o;61650:416::-;61850:2;61864:47;;;29491:2;61835:18;;;68811:19;29527:23;68851:14;;;29507:44;29570:12;;;61821:245::o;62073:416::-;62273:2;62287:47;;;30176:2;62258:18;;;68811:19;30212:20;68851:14;;;30192:41;30252:12;;;62244:245::o;62496:416::-;62696:2;62710:47;;;31586:2;62681:18;;;68811:19;31622:13;68851:14;;;31602:34;31655:12;;;62667:245::o;62919:416::-;63119:2;63133:47;;;32278:2;63104:18;;;68811:19;32314:34;68851:14;;;32294:55;32383:4;32369:12;;;32362:26;32407:12;;;63090:245::o;63342:416::-;63542:2;63556:47;;;33020:2;63527:18;;;68811:19;33056;68851:14;;;33036:40;33095:12;;;63513:245::o;63765:416::-;63965:2;63979:47;;;33702:2;63950:18;;;68811:19;33738:12;68851:14;;;33718:33;33770:12;;;63936:245::o;64188:416::-;64388:2;64402:47;;;34021:2;64373:18;;;68811:19;34057:17;68851:14;;;34037:38;34094:12;;;64359:245::o;64611:416::-;64811:2;64825:47;;;34701:2;64796:18;;;68811:19;34737:29;68851:14;;;34717:50;34786:12;;;64782:245::o;65034:222::-;19269:37;;;65161:2;65146:18;;65132:124::o;65263:256::-;65325:2;65319:9;65351:17;;;65426:18;65411:34;;65447:22;;;65408:62;65405:2;;;65483:1;;65473:12;65405:2;65325;65492:22;65303:216;;-1:-1;65303:216::o;65526:341::-;;65722:18;65714:6;65711:30;65708:2;;;-1:-1;;65744:12;65708:2;-1:-1;65789:4;65777:17;;;65842:15;;65645:222::o;70462:136::-;70528:16;72110:1;72100:12;;72090:2;;72116:9;71484:268;71549:1;71556:101;71570:6;71567:1;71564:13;71556:101;;;71637:11;;;71631:18;71618:11;;;71611:39;71592:2;71585:10;71556:101;;;71672:6;71669:1;71666:13;71663:2;;;-1:-1;;71549:1;71719:16;;71712:27;71533:219::o;72252:117::-;70821:42;72339:5;70810:54;72314:5;72311:35;72301:2;;72360:1;;72350:12;72301:2;72295:74;:::o;72758:109::-;72842:1;72835:5;72832:12;72822:2;;72858:1;;72848:12
Swarm Source
ipfs://d90bfeb4a591f165d95cc8b854cf588cdd46dd6a1c6bd47ad13c6ffd82cd4168
Loading...
Loading
Loading...
Loading
OVERVIEW
Zerion DeFi SDK Router contract. Used for interaction with users.Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.