More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 24,570 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Start Execution | 21602221 | 51 mins ago | IN | 0 ETH | 0.00104035 | ||||
Start Execution | 21595461 | 23 hrs ago | IN | 0 ETH | 0.00169655 | ||||
Start Execution | 21592029 | 35 hrs ago | IN | 0 ETH | 0.00082499 | ||||
Start Execution | 21590391 | 40 hrs ago | IN | 0 ETH | 0.00116124 | ||||
Start Execution | 21557225 | 6 days ago | IN | 0 ETH | 0.00119432 | ||||
Start Execution | 21551721 | 7 days ago | IN | 0 ETH | 0.0049572 | ||||
Start Execution | 21551550 | 7 days ago | IN | 0 ETH | 0.00877362 | ||||
Start Execution | 21537082 | 9 days ago | IN | 0 ETH | 0.00674689 | ||||
Start Execution | 21510964 | 12 days ago | IN | 0 ETH | 0.00184298 | ||||
Start Execution | 21509032 | 13 days ago | IN | 0 ETH | 0.00188587 | ||||
Start Execution | 21509028 | 13 days ago | IN | 0 ETH | 0.00193659 | ||||
Start Execution | 21508988 | 13 days ago | IN | 0 ETH | 0.00184506 | ||||
Start Execution | 21508973 | 13 days ago | IN | 0 ETH | 0.00184988 | ||||
Start Execution | 21508962 | 13 days ago | IN | 0 ETH | 0.00176247 | ||||
Start Execution | 21508951 | 13 days ago | IN | 0 ETH | 0.00147932 | ||||
Start Execution | 21505112 | 13 days ago | IN | 0 ETH | 0.00094365 | ||||
Start Execution | 21497011 | 14 days ago | IN | 0 ETH | 0.00126824 | ||||
Start Execution | 21495920 | 14 days ago | IN | 0 ETH | 0.00223947 | ||||
Start Execution | 21494322 | 15 days ago | IN | 0 ETH | 0.00191964 | ||||
Start Execution | 21476594 | 17 days ago | IN | 0 ETH | 0.00141203 | ||||
Start Execution | 21473366 | 18 days ago | IN | 0 ETH | 0.00377764 | ||||
Start Execution | 21468208 | 18 days ago | IN | 0 ETH | 0.0033533 | ||||
Start Execution | 21464076 | 19 days ago | IN | 0 ETH | 0.00161613 | ||||
Start Execution | 21437602 | 23 days ago | IN | 0 ETH | 0.0074401 | ||||
Start Execution | 21435634 | 23 days ago | IN | 0 ETH | 0.00313602 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21349696 | 35 days ago | 0.105 ETH | ||||
21182721 | 58 days ago | 0.012 ETH | ||||
20646892 | 133 days ago | 0.009 ETH | ||||
20633324 | 135 days ago | 0.003 ETH | ||||
20539664 | 148 days ago | 0.002 ETH | ||||
20452687 | 160 days ago | 0.00375 ETH | ||||
20451915 | 160 days ago | 0.005 ETH | ||||
20451862 | 160 days ago | 0.0008 ETH | ||||
20409142 | 166 days ago | 0.005 ETH | ||||
20408882 | 166 days ago | 0.00267 ETH | ||||
20408564 | 166 days ago | 0.0008 ETH | ||||
20408542 | 166 days ago | 0.01 ETH | ||||
20408488 | 166 days ago | 0.002 ETH | ||||
20408264 | 166 days ago | 0.005 ETH | ||||
20395711 | 168 days ago | 0.008 ETH | ||||
20295447 | 182 days ago | 0.011 ETH | ||||
20242543 | 189 days ago | 1 ETH | ||||
19908843 | 236 days ago | 0.01 ETH | ||||
19840849 | 246 days ago | 0.01 ETH | ||||
19634127 | 274 days ago | 0.26 ETH | ||||
19468328 | 298 days ago | 0.6 ETH | ||||
19329261 | 317 days ago | 0.5 ETH | ||||
19174849 | 339 days ago | 0.0253777 ETH | ||||
18831356 | 387 days ago | 0.1 ETH | ||||
18735820 | 400 days ago | 0.0001 ETH |
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
[{"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.