Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60a06040 | 12299386 | 1291 days ago | IN | 0 ETH | 0.36393427 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
DharmaTradeReserveV19Implementation
Compiler Version
v0.8.1+commit.df193b15
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-04-23 */ // SPDX-License-Identifier: MIT pragma solidity 0.8.1; interface ITypes { struct Call { address to; uint96 value; bytes data; } struct CallReturn { bool ok; bytes returnData; } } interface IActionRegistry { // events event AddedSelector(address account, bytes4 selector); event RemovedSelector(address account, bytes4 selector); event AddedSpender(address account, address spender); event RemovedSpender(address account, address spender); struct AccountSelectors { address account; bytes4[] selectors; } struct AccountSpenders { address account; address[] spenders; } function isValidAction(ITypes.Call[] calldata calls) external view returns (bool valid); function addSelector(address account, bytes4 selector) external; function removeSelector(address account, bytes4 selector) external; function addSpender(address account, address spender) external; function removeSpender(address account, address spender) external; } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. * * In order to transfer ownership, a recipient must be specified, at which point * the specified recipient can call `acceptOwnership` and take ownership. */ contract TwoStepOwnable { address private _owner; address private _newPotentialOwner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initialize contract by setting transaction submitter as initial owner. */ constructor() public { _owner = tx.origin; emit OwnershipTransferred(address(0), _owner); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "TwoStepOwnable: caller is not the owner."); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows a new account (`newOwner`) to accept ownership. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public onlyOwner { require( newOwner != address(0), "TwoStepOwnable: new potential owner is the zero address." ); _newPotentialOwner = newOwner; } /** * @dev Cancel a transfer of ownership to a new account. * Can only be called by the current owner. */ function cancelOwnershipTransfer() public onlyOwner { delete _newPotentialOwner; } /** * @dev Transfers ownership of the contract to the caller. * Can only be called by a new potential owner set by the current owner. */ function acceptOwnership() public { require( msg.sender == _newPotentialOwner, "TwoStepOwnable: current owner must set caller as new potential owner." ); delete _newPotentialOwner; emit OwnershipTransferred(_owner, msg.sender); _owner = msg.sender; } } interface DharmaTradeReserveV19Interface { event Trade( address account, address suppliedAsset, address receivedAsset, address retainedAsset, uint256 suppliedAmount, uint256 recievedAmount, // note: typo uint256 retainedAmount ); event RoleModified(Role indexed role, address account); event RolePaused(Role indexed role); event RoleUnpaused(Role indexed role); event EtherReceived(address sender, uint256 amount); event GasReserveRefilled(uint256 etherAmount); enum Role { // DEPOSIT_MANAGER, // 0 ADJUSTER, // 1 WITHDRAWAL_MANAGER, // 2 RESERVE_TRADER, // 3 PAUSER, // 4 GAS_RESERVE_REFILLER, // 5 ACTIONER // 6 } enum FeeType { // # SUPPLIED_ASSET, // 0 RECEIVED_ASSET, // 1 ETHER // 2 } enum TradeType { ETH_TO_TOKEN, TOKEN_TO_ETH, TOKEN_TO_TOKEN, ETH_TO_TOKEN_WITH_TRANSFER_FEE, TOKEN_TO_ETH_WITH_TRANSFER_FEE, TOKEN_TO_TOKEN_WITH_TRANSFER_FEE } struct RoleStatus { address account; bool paused; } function simulate( ITypes.Call[] calldata calls ) external returns (bool[] memory ok, bytes[] memory returnData, bool validCalls); function execute( ITypes.Call[] calldata calls ) external returns (bool[] memory ok, bytes[] memory returnData); event CallSuccess( bool rolledBack, address to, uint256 value, bytes data, bytes returnData ); event CallFailure( address to, uint256 value, bytes data, string revertReason ); function tradeTokenForTokenSpecifyingFee( ERC20Interface tokenProvided, address tokenReceived, uint256 tokenProvidedAmount, uint256 quotedTokenReceivedAmount, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) external returns (uint256 totalTokensBought); function tradeTokenForTokenWithFeeOnTransfer( ERC20Interface tokenProvided, address tokenReceived, uint256 tokenProvidedAmount, uint256 quotedTokenReceivedAmount, uint256 quotedTokenReceivedAmountAfterTransferFee, uint256 deadline, bool routeThroughEther ) external returns (uint256 totalTokensBought); function tradeTokenForTokenWithFeeOnTransferSpecifyingFee( ERC20Interface tokenProvided, address tokenReceived, uint256 tokenProvidedAmount, uint256 quotedTokenReceivedAmount, uint256 quotedTokenReceivedAmountAfterTransferFee, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) external returns (uint256 totalTokensBought); function tradeTokenForTokenUsingReservesWithFeeOnTransferSpecifyingFee( ERC20Interface tokenProvidedFromReserves, address tokenReceived, uint256 tokenProvidedAmountFromReserves, uint256 quotedTokenReceivedAmount, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) external returns (uint256 totalTokensBought); function tradeTokenForEtherWithFeeOnTransfer( ERC20Interface token, uint256 tokenAmount, uint256 quotedEtherAmount, uint256 deadline ) external returns (uint256 totalEtherBought); function tradeTokenForEtherWithFeeOnTransferSpecifyingFee( ERC20Interface token, uint256 tokenAmount, uint256 quotedEtherAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external returns (uint256 totalEtherBought); function tradeTokenForEtherUsingReservesWithFeeOnTransferSpecifyingFee( ERC20Interface token, uint256 tokenAmountFromReserves, uint256 quotedEtherAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external returns (uint256 totalEtherBought); function tradeTokenForEtherSpecifyingFee( ERC20Interface token, uint256 tokenAmount, uint256 quotedEtherAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external returns (uint256 totalEtherBought); function tradeEtherForTokenWithFeeOnTransfer( address token, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 deadline ) external payable returns (uint256 totalTokensBought); function tradeEtherForTokenSpecifyingFee( address token, uint256 quotedTokenAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external payable returns (uint256 totalTokensBought); function tradeEtherForTokenWithFeeOnTransferSpecifyingFee( address token, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external payable returns (uint256 totalTokensBought); function tradeEtherForTokenWithFeeOnTransferUsingEtherizer( address token, uint256 etherAmount, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 deadline ) external returns (uint256 totalTokensBought); function tradeTokenForTokenUsingReservesSpecifyingFee( ERC20Interface tokenProvidedFromReserves, address tokenReceived, uint256 tokenProvidedAmountFromReserves, uint256 quotedTokenReceivedAmount, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) external returns (uint256 totalTokensBought); function tradeEtherForTokenUsingReservesWithFeeOnTransferSpecifyingFee( address token, uint256 etherAmountFromReserves, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external returns (uint256 totalTokensBought); function tradeTokenForEtherUsingReservesSpecifyingFee( ERC20Interface token, uint256 tokenAmountFromReserves, uint256 quotedEtherAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external returns (uint256 totalEtherBought); function tradeEtherForTokenUsingReservesSpecifyingFee( address token, uint256 etherAmountFromReserves, uint256 quotedTokenAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external returns (uint256 totalTokensBought); function finalizeEtherDeposit( address payable smartWallet, address initialUserSigningKey, uint256 etherAmount ) external; function finalizeTokenDeposit( address smartWallet, address initialUserSigningKey, ERC20Interface token, uint256 amount ) external; function refillGasReserve(uint256 etherAmount) external; function withdrawUSDCToPrimaryRecipient(uint256 usdcAmount) external; function withdrawDaiToPrimaryRecipient(uint256 usdcAmount) external; function withdrawEther( address payable recipient, uint256 etherAmount ) external; function withdraw( ERC20Interface token, address recipient, uint256 amount ) external returns (bool success); function callAny( address payable target, uint256 amount, bytes calldata data ) external returns (bool ok, bytes memory returnData); function setPrimaryUSDCRecipient(address recipient) external; function setPrimaryDaiRecipient(address recipient) external; function setRole(Role role, address account) external; function removeRole(Role role) external; function pause(Role role) external; function unpause(Role role) external; function isPaused(Role role) external view returns (bool paused); function isRole(Role role) external view returns (bool hasRole); function isDharmaSmartWallet( address smartWallet, address initialUserSigningKey ) external view returns (bool dharmaSmartWallet); function getDepositManager() external view returns (address depositManager); function getReserveTrader() external view returns (address reserveTrader); function getWithdrawalManager() external view returns ( address withdrawalManager ); function getActioner() external view returns ( address actioner ); function getPauser() external view returns (address pauser); function getGasReserveRefiller() external view returns ( address gasReserveRefiller ); function getPrimaryUSDCRecipient() external view returns ( address recipient ); function getPrimaryDaiRecipient() external view returns ( address recipient ); function getImplementation() external view returns (address implementation); function getInstance() external pure returns (address instance); function getVersion() external view returns (uint256 version); } interface ERC20Interface { function balanceOf(address) external view returns (uint256); function approve(address, uint256) external returns (bool); function allowance(address, address) external view returns (uint256); function transfer(address, uint256) external returns (bool); function transferFrom(address, address, uint256) external returns (bool); } interface DTokenInterface { function balanceOf(address) external view returns (uint256); function balanceOfUnderlying(address) external view returns (uint256); function transfer(address, uint256) external returns (bool); function approve(address, uint256) external returns (bool); function exchangeRateCurrent() external view returns (uint256); } interface UniswapV2Interface { function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens( uint256 amountOut, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapExactETHForTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable returns (uint256[] memory amounts); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable; } library SafeMath { function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } } /** * @title DharmaTradeReserveV19Implementation * @author 0age + cf ;) * @notice This contract manages Dharma's reserves. It designates a collection of * "roles" - these are dedicated accounts that can be modified by the owner, and * that can trigger specific functionality on the reserve. These roles are: * - depositManager (0): initiates Eth / token transfers to smart wallets * - adjuster (1): mints / redeems Dai, and swaps USDC, for dDai * - withdrawalManager (2): initiates token transfers to recipients set by owner * - reserveTrader (3): initiates trades using funds held in reserve * - pauser (4): pauses any role (only the owner is then able to unpause it) * - gasReserveRefiller (5): transfers Ether to the Dharma Gas Reserve * * When finalizing deposits, the deposit manager must adhere to two constraints: * - it must provide "proof" that the recipient is a smart wallet by including * the initial user signing key used to derive the smart wallet address * * Note that "proofs" can be validated via `isSmartWallet`. */ contract DharmaTradeReserveV19Implementation is DharmaTradeReserveV19Interface, TwoStepOwnable { using SafeMath for uint256; // Maintain a role status mapping with assigned accounts and paused states. mapping(uint256 => RoleStatus) private _roles; // Maintain a "primary recipient" the withdrawal manager can transfer Dai to. address private _primaryDaiRecipient; // Maintain a "primary recipient" the withdrawal manager can transfer USDC to. address private _primaryUSDCRecipient; // Maintain a maximum allowable transfer size (in Dai) for the deposit manager. uint256 private _daiLimit; // unused // Maintain a maximum allowable transfer size (in Ether) for the deposit manager. uint256 private _etherLimit; // unused bool private _originatesFromReserveTrader; // unused, don't change storage layout bytes4 internal _selfCallContext; uint256 private constant _VERSION = 19; // This contract interacts with USDC, Dai, and Dharma Dai. ERC20Interface internal constant _USDC = ERC20Interface( 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 // mainnet ); ERC20Interface internal constant _DAI = ERC20Interface( 0x6B175474E89094C44Da98b954EedeAC495271d0F // mainnet ); ERC20Interface internal constant _ETHERIZER = ERC20Interface( 0x723B51b72Ae89A3d0c2a2760f0458307a1Baa191 ); DTokenInterface internal constant _DDAI = DTokenInterface( 0x00000000001876eB1444c986fD502e618c587430 ); UniswapV2Interface internal constant _UNISWAP_ROUTER = UniswapV2Interface( 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D ); address internal constant _WETH = address( 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 ); address internal constant _GAS_RESERVE = address( 0x55F2039347564d206Ccc6e6cE202853Fed386dBf ); // The "Create2 Header" is used to compute smart wallet deployment addresses. bytes21 internal constant _CREATE2_HEADER = bytes21( 0xfffc00c80b0000007f73004edb00094cad80626d8d // control character + factory ); // The "Wallet creation code" header & footer are also used to derive wallets. bytes internal constant _WALLET_CREATION_CODE_HEADER = hex"60806040526040516104423803806104428339818101604052602081101561002657600080fd5b810190808051604051939291908464010000000082111561004657600080fd5b90830190602082018581111561005b57600080fd5b825164010000000081118282018810171561007557600080fd5b82525081516020918201929091019080838360005b838110156100a257818101518382015260200161008a565b50505050905090810190601f1680156100cf5780820380516001836020036101000a031916815260200191505b5060405250505060006100e661019e60201b60201c565b6001600160a01b0316826040518082805190602001908083835b6020831061011f5780518252601f199092019160209182019101610100565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461017f576040519150601f19603f3d011682016040523d82523d6000602084013e610184565b606091505b5050905080610197573d6000803e3d6000fd5b50506102be565b60405160009081906060906e26750c571ce882b17016557279adaa9083818181855afa9150503d80600081146101f0576040519150601f19603f3d011682016040523d82523d6000602084013e6101f5565b606091505b509150915081819061029f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026457818101518382015260200161024c565b50505050905090810190601f1680156102915780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508080602001905160208110156102b557600080fd5b50519392505050565b610175806102cd6000396000f3fe608060405261001461000f610016565b61011c565b005b60405160009081906060906e26750c571ce882b17016557279adaa9083818181855afa9150503d8060008114610068576040519150601f19603f3d011682016040523d82523d6000602084013e61006d565b606091505b50915091508181906100fd5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156100c25781810151838201526020016100aa565b50505050905090810190601f1680156100ef5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5080806020019051602081101561011357600080fd5b50519392505050565b3660008037600080366000845af43d6000803e80801561013b573d6000f35b3d6000fdfea265627a7a7231582020202020202055706772616465426561636f6e50726f7879563120202020202064736f6c634300050b003200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000024c4d66de8000000000000000000000000"; bytes28 internal constant _WALLET_CREATION_CODE_FOOTER = bytes28( 0x00000000000000000000000000000000000000000000000000000000 ); // Flag to trigger trade for USDC and retain full trade amount address internal constant _TRADE_FOR_USDC_AND_RETAIN_FLAG = address(type(uint160).max); // The "action registry" keeps track of function-selectors and approved spenders // allowed in the generic call execution flow. IActionRegistry public immutable _ACTION_REGISTRY; address private constant V17 = address( 0xf1209998BD17eAe301a97e3cF7ec17dF580E7964 ); // Include a payable fallback so that the contract can receive Ether payments. receive() external payable { emit EtherReceived(msg.sender, msg.value); } constructor(address actionRegistryAddress) public { _ACTION_REGISTRY = IActionRegistry(actionRegistryAddress); } /** * @notice Simulate a series of generic calls to other contracts. * Calls will be rolled back (and calls will only be * simulated up until a failing call is encountered). * @param calls Call[] A struct containing the target, value, and calldata to * provide when making each call. * return An array of structs signifying the status of each call, as well as * any data returned from that call. Calls that are not executed will return * empty data. */ function simulate( ITypes.Call[] calldata calls ) external override returns (bool[] memory ok, bytes[] memory returnData, bool validCalls) { // Ensure all calls are valid validCalls = _ACTION_REGISTRY.isValidAction(calls); // Specify length of returned values in order to work with them in memory. ok = new bool[](calls.length); returnData = new bytes[](calls.length); // Make the atomic self-call - if any call fails, calls that preceded it // will be rolled back and calls that follow it will not be made. (, bytes memory rawCallResults) = address(this).call( abi.encodeWithSelector( this._simulate.selector, calls ) ); // Parse data returned from self-call into each call result and store / log. ITypes.CallReturn[] memory callResults = abi.decode(rawCallResults, (ITypes.CallReturn[])); for (uint256 i = 0; i < callResults.length; i++) { // Set the status and the return data / revert reason from the call. ok[i] = callResults[i].ok; returnData[i] = callResults[i].returnData; if (!callResults[i].ok) { // exit early - any calls after the first failed call will not execute. break; } } } /** * @notice Protected function that can only be called from * `simulateActionWithAtomicBatchCalls` on this contract. It will attempt to * perform each specified call, populating the array of results as it goes, * unless a failure occurs, at which point it will revert and "return" the * array of results as revert data. Regardless, it will roll back all calls at * the end of execution — in other words, this call always reverts. * @param calls Call[] A struct containing the target, value, and calldata to * provide when making each call. * return An array of structs signifying the status of each call, as well as * any data returned from that call. Calls that are not executed will return * empty data. If any of the calls fail, the array will be returned as revert * data. */ function _simulate( ITypes.Call[] memory calls ) public returns (ITypes.CallReturn[] memory callResults) { callResults = new ITypes.CallReturn[](calls.length); for (uint256 i = 0; i < calls.length; i++) { // Perform low-level call and set return values using result. (bool ok, bytes memory returnData) = calls[i].to.call{value: uint256(calls[i].value) }(calls[i].data); callResults[i] = ITypes.CallReturn({ok: ok, returnData: returnData}); if (!ok) { // Exit early - any calls after the first failed call will not execute. break; } } // Wrap in length encoding and revert (provide bytes instead of a string). bytes memory callResultsBytes = abi.encode(callResults); assembly { revert(add(32, callResultsBytes), mload(callResultsBytes)) } } function execute( ITypes.Call[] memory calls ) public onlyOwnerOr(Role.ACTIONER) override returns (bool[] memory ok, bytes[] memory returnData) { // Ensure all calls are valid bool validCalls = _ACTION_REGISTRY.isValidAction(calls); require(validCalls, "Invalid call detected!"); // Note: from this point on, there are no reverts (apart from out-of-gas or // call-depth-exceeded) originating from this contract. However, one of the // calls may revert, in which case the function will return `false`, along // with the revert reason encoded as bytes, and fire a CallFailure event. // Specify length of returned values in order to work with them in memory. ok = new bool[](calls.length); returnData = new bytes[](calls.length); // Set self-call context to call _execute. _selfCallContext = this.execute.selector; // Make the atomic self-call - if any call fails, calls that preceded it // will be rolled back and calls that follow it will not be made. (bool externalOk, bytes memory rawCallResults) = address(this).call( abi.encodeWithSelector( this._execute.selector, calls ) ); // Ensure that self-call context has been cleared. if (!externalOk) { delete _selfCallContext; } // Parse data returned from self-call into each call result and store / log. ITypes.CallReturn[] memory callResults = abi.decode(rawCallResults, (ITypes.CallReturn[])); for (uint256 i = 0; i < callResults.length; i++) { ITypes.Call memory currentCall = calls[i]; // Set the status and the return data / revert reason from the call. ok[i] = callResults[i].ok; returnData[i] = callResults[i].returnData; // Emit CallSuccess or CallFailure event based on the outcome of the call. if (callResults[i].ok) { // Note: while the call succeeded, the action may still have "failed". emit CallSuccess( !externalOk, // If another call failed this will have been rolled back currentCall.to, uint256(currentCall.value), currentCall.data, callResults[i].returnData ); } else { // Note: while the call failed, the nonce will still be incremented, // which will invalidate all supplied signatures. emit CallFailure( currentCall.to, uint256(currentCall.value), currentCall.data, _decodeRevertReason(callResults[i].returnData) ); // exit early - any calls after the first failed call will not execute. break; } } } function _execute( ITypes.Call[] memory calls ) public returns (ITypes.CallReturn[] memory callResults) { // Ensure caller is this contract and self-call context is correctly set. _enforceSelfCallFrom(this.execute.selector); bool rollBack = false; callResults = new ITypes.CallReturn[](calls.length); for (uint256 i = 0; i < calls.length; i++) { // Perform low-level call and set return values using result. (bool ok, bytes memory returnData) = calls[i].to.call{value: uint256(calls[i].value) }(calls[i].data); callResults[i] = ITypes.CallReturn({ok: ok, returnData: returnData}); if (!ok) { // Exit early - any calls after the first failed call will not execute. rollBack = true; break; } } if (rollBack) { // Wrap in length encoding and revert (provide bytes instead of a string). bytes memory callResultsBytes = abi.encode(callResults); assembly { revert(add(32, callResultsBytes), mload(callResultsBytes)) } } } /** * @notice Internal function to ensure that protected functions can only be * called from this contract and that they have the appropriate context set. * The self-call context is then cleared. It is used as an additional guard * against reentrancy, especially once generic actions are supported by the * smart wallet in future versions. * @param selfCallContext bytes4 The expected self-call context, equal to the * function selector of the approved calling function. */ function _enforceSelfCallFrom(bytes4 selfCallContext) internal { // Ensure caller is this contract and self-call context is correctly set. require( msg.sender == address(this) && _selfCallContext == selfCallContext, "External accounts or unapproved internal functions cannot call this." ); // Clear the self-call context. delete _selfCallContext; } function _decodeRevertReason( bytes memory revertData ) internal pure returns (string memory revertReason) { // Solidity prefixes revert reason with 0x08c379a0 -> Error(string) selector if ( revertData.length > 68 && // prefix (4) + position (32) + length (32) revertData[0] == bytes1(0x08) && revertData[1] == bytes1(0xc3) && revertData[2] == bytes1(0x79) && revertData[3] == bytes1(0xa0) ) { // Get the revert reason without the prefix from the revert data. bytes memory revertReasonBytes = new bytes(revertData.length - 4); for (uint256 i = 4; i < revertData.length; i++) { revertReasonBytes[i - 4] = revertData[i]; } // Decode the resultant revert reason as a string. revertReason = abi.decode(revertReasonBytes, (string)); } else { // Simply return the default, with no revert reason. revertReason = "(no revert reason)"; } } function tradeTokenForTokenSpecifyingFee( ERC20Interface tokenProvided, address tokenReceived, uint256 tokenProvidedAmount, uint256 quotedTokenReceivedAmount, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) external override returns (uint256 totalTokensBought) { _ensureNoEtherFeeTypeWhenNotRouted(routeThroughEther, feeType); // Transfer the token from the caller and revert on failure. _transferInToken(tokenProvided, msg.sender, tokenProvidedAmount); totalTokensBought = _tradeTokenForToken( msg.sender, tokenProvided, tokenReceived, tokenProvidedAmount, quotedTokenReceivedAmount, maximumFeeAmount, deadline, routeThroughEther, feeType ); } function tradeTokenForTokenWithFeeOnTransfer( ERC20Interface tokenProvided, address tokenReceived, uint256 tokenProvidedAmount, uint256 quotedTokenReceivedAmount, uint256 quotedTokenReceivedAmountAfterTransferFee, uint256 deadline, bool routeThroughEther ) external override returns (uint256 totalTokensBought) { _delegate(V17); } function tradeTokenForTokenWithFeeOnTransferSpecifyingFee( ERC20Interface tokenProvided, address tokenReceived, uint256 tokenProvidedAmount, uint256 quotedTokenReceivedAmount, uint256 quotedTokenReceivedAmountAfterTransferFee, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) external override returns (uint256 totalTokensBought) { _delegate(V17); } function tradeTokenForEtherSpecifyingFee( ERC20Interface token, uint256 tokenAmount, uint256 quotedEtherAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external override returns (uint256 totalEtherBought) { // Transfer the tokens from the caller and revert on failure. _transferInToken(token, msg.sender, tokenAmount); uint256 receivedEtherAmount; uint256 retainedAmount; (totalEtherBought, receivedEtherAmount, retainedAmount) = _tradeTokenForEther( token, tokenAmount, tokenAmount, quotedEtherAmount, deadline, feeType, maximumFeeAmount ); _fireTradeEvent( false, false, feeType != FeeType.SUPPLIED_ASSET, address(token), tokenAmount, receivedEtherAmount, retainedAmount ); // Transfer the Ether amount to receive to the caller. _transferEther(msg.sender, receivedEtherAmount); } function tradeTokenForEtherWithFeeOnTransfer( ERC20Interface token, uint256 tokenAmount, uint256 quotedEtherAmount, uint256 deadline ) external override returns (uint256 totalEtherBought) { _delegate(V17); } function tradeTokenForEtherWithFeeOnTransferSpecifyingFee( ERC20Interface token, uint256 tokenAmount, uint256 quotedEtherAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external override returns (uint256 totalEtherBought) { _delegate(V17); } function tradeEtherForTokenSpecifyingFee( address token, uint256 quotedTokenAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external override payable returns (uint256 totalTokensBought) { // Trade Ether for the specified token. uint256 receivedTokenAmount; uint256 retainedAmount; (totalTokensBought, receivedTokenAmount, retainedAmount) = _tradeExactEtherForToken( token, msg.value, quotedTokenAmount, deadline, false, feeType, maximumFeeAmount ); _fireTradeEvent( false, true, feeType != FeeType.RECEIVED_ASSET, token, msg.value, receivedTokenAmount, retainedAmount ); } function tradeEtherForTokenWithFeeOnTransfer( address token, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 deadline ) external override payable returns (uint256 totalTokensBought) { _delegate(V17); } function tradeEtherForTokenWithFeeOnTransferSpecifyingFee( address token, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external override payable returns (uint256 totalTokensBought) { _delegate(V17); } function tradeEtherForTokenUsingReservesWithFeeOnTransferSpecifyingFee( address token, uint256 etherAmountFromReserves, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external override onlyOwnerOr(Role.RESERVE_TRADER) returns (uint256 totalTokensBought) { totalTokensBought = _tradeEtherForTokenWithFeeOnTransfer( token, etherAmountFromReserves, quotedTokenAmount, quotedTokenAmountAfterTransferFee, maximumFeeAmount, deadline, true, feeType ); } function tradeEtherForTokenWithFeeOnTransferUsingEtherizer( address token, uint256 etherAmount, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 deadline ) external override returns (uint256 totalTokensBought) { _delegate(V17); } function tradeTokenForTokenUsingReservesSpecifyingFee( ERC20Interface tokenProvidedFromReserves, address tokenReceived, uint256 tokenProvidedAmountFromReserves, uint256 quotedTokenReceivedAmount, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) external onlyOwnerOr(Role.RESERVE_TRADER) override returns (uint256 totalTokensBought) { _ensureNoEtherFeeTypeWhenNotRouted(routeThroughEther, feeType); totalTokensBought = _tradeTokenForToken( address(this), tokenProvidedFromReserves, tokenReceived, tokenProvidedAmountFromReserves, quotedTokenReceivedAmount, maximumFeeAmount, deadline, routeThroughEther, feeType ); } function tradeTokenForTokenUsingReservesWithFeeOnTransferSpecifyingFee( ERC20Interface tokenProvidedFromReserves, address tokenReceived, uint256 tokenProvidedAmountFromReserves, uint256 quotedTokenReceivedAmount, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) external onlyOwnerOr(Role.RESERVE_TRADER) override returns (uint256 totalTokensBought) { _ensureNoEtherFee(feeType); totalTokensBought = _tradeTokenForTokenWithFeeOnTransfer( TradeTokenForTokenWithFeeOnTransferArgs({ account: address(this), tokenProvided: tokenProvidedFromReserves, tokenReceivedOrUSDCFlag: tokenReceived, tokenProvidedAmount: tokenProvidedAmountFromReserves, tokenProvidedAmountAfterTransferFee: tokenProvidedAmountFromReserves, quotedTokenReceivedAmount: quotedTokenReceivedAmount, quotedTokenReceivedAmountAfterTransferFee: tokenProvidedAmountFromReserves, maximumFeeAmount: maximumFeeAmount, deadline: deadline, routeThroughEther: routeThroughEther, feeType: feeType }) ); } function tradeTokenForEtherUsingReservesSpecifyingFee( ERC20Interface token, uint256 tokenAmountFromReserves, uint256 quotedEtherAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external onlyOwnerOr(Role.RESERVE_TRADER) override returns (uint256 totalEtherBought) { uint256 receivedEtherAmount; uint256 retainedAmount; (totalEtherBought, receivedEtherAmount, retainedAmount) = _tradeTokenForEther( token, tokenAmountFromReserves, tokenAmountFromReserves, quotedEtherAmount, deadline, feeType, maximumFeeAmount ); _fireTradeEvent( true, false, feeType != FeeType.SUPPLIED_ASSET, address(token), tokenAmountFromReserves, receivedEtherAmount, retainedAmount ); } function tradeTokenForEtherUsingReservesWithFeeOnTransferSpecifyingFee( ERC20Interface token, uint256 tokenAmountFromReserves, uint256 quotedEtherAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external onlyOwnerOr(Role.RESERVE_TRADER) override returns (uint256 totalEtherBought) { uint256 receivedEtherAmount; uint256 retainedAmount; (totalEtherBought, receivedEtherAmount, retainedAmount) = _tradeTokenForEther( token, tokenAmountFromReserves + 1, tokenAmountFromReserves, quotedEtherAmount, deadline, feeType, maximumFeeAmount ); _fireTradeEvent( true, false, feeType != FeeType.SUPPLIED_ASSET, address(token), tokenAmountFromReserves, receivedEtherAmount, retainedAmount ); } function tradeEtherForTokenUsingReservesSpecifyingFee( address token, uint256 etherAmountFromReserves, uint256 quotedTokenAmount, uint256 maximumFeeAmount, uint256 deadline, FeeType feeType ) external onlyOwnerOr(Role.RESERVE_TRADER) override returns ( uint256 totalTokensBought ) { // Trade Ether for the specified token. uint256 receivedTokenAmount; uint256 retainedAmount; (totalTokensBought, receivedTokenAmount, retainedAmount) = _tradeExactEtherForToken( token, etherAmountFromReserves, quotedTokenAmount, deadline, true, feeType, maximumFeeAmount ); _fireTradeEvent( true, true, feeType != FeeType.RECEIVED_ASSET, token, etherAmountFromReserves, receivedTokenAmount, maximumFeeAmount ); } /** * @notice Transfer `amount` of token `token` to `smartWallet`, providing the * initial user signing key `initialUserSigningKey` as proof that the * specified smart wallet is indeed a Dharma Smart Wallet - this assumes that * the address is derived and deployed using the Dharma Smart Wallet Factory * V1. Only the owner or the designated deposit manager role may call this * function. * @param smartWallet address The smart wallet to transfer tokens to. * @param initialUserSigningKey address The initial user signing key supplied * when deriving the smart wallet address - this could be an EOA or a Dharma * key ring address. * @param token ERC20Interface The token to transfer. * @param amount uint256 The amount of tokens to transfer. */ function finalizeTokenDeposit( address smartWallet, address initialUserSigningKey, ERC20Interface token, uint256 amount ) external onlyOwnerOr(Role.DEPOSIT_MANAGER) override { // Ensure that the recipient is indeed a smart wallet. _ensureSmartWallet(smartWallet, initialUserSigningKey); // Transfer the token to the specified smart wallet. _transferToken(token, smartWallet, amount); } /** * @notice Transfer `etherAmount` Ether to `smartWallet`, providing the * initial user signing key `initialUserSigningKey` as proof that the * specified smart wallet is indeed a Dharma Smart Wallet - this assumes that * the address is derived and deployed using the Dharma Smart Wallet Factory * V1. In addition, the Ether amount must be less than the configured limit * amount. Only the owner or the designated deposit manager role may call this * function. * @param smartWallet address The smart wallet to transfer Ether to. * @param initialUserSigningKey address The initial user signing key supplied * when deriving the smart wallet address - this could be an EOA or a Dharma * key ring address. * @param etherAmount uint256 The amount of Ether to transfer - this amount * must be less than the current limit. */ function finalizeEtherDeposit( address payable smartWallet, address initialUserSigningKey, uint256 etherAmount ) external onlyOwnerOr(Role.DEPOSIT_MANAGER) override { // Ensure that the recipient is indeed a smart wallet. _ensureSmartWallet(smartWallet, initialUserSigningKey); // Transfer the Ether to the specified smart wallet. _transferEther(smartWallet, etherAmount); } function refillGasReserve( uint256 etherAmount ) external onlyOwnerOr(Role.GAS_RESERVE_REFILLER) override { // Transfer the Ether to the gas reserve. _transferEther(_GAS_RESERVE, etherAmount); emit GasReserveRefilled(etherAmount); } /** * @notice Transfer `usdcAmount` USDC for to the current primary recipient set * by the owner. Only the owner or the designated withdrawal manager role may * call this function. * @param usdcAmount uint256 The amount of USDC to transfer to the primary * recipient. */ function withdrawUSDCToPrimaryRecipient( uint256 usdcAmount ) external onlyOwnerOr(Role.WITHDRAWAL_MANAGER) override { // Get the current primary recipient. address primaryRecipient = _primaryUSDCRecipient; require( primaryRecipient != address(0), "No USDC primary recipient currently set." ); // Transfer the supplied USDC amount to the primary recipient. _transferToken(_USDC, primaryRecipient, usdcAmount); } /** * @notice Transfer `daiAmount` Dai for to the current primary recipient set * by the owner. Only the owner or the designated withdrawal manager role may * call this function. * @param daiAmount uint256 The amount of Dai to transfer to the primary * recipient. */ function withdrawDaiToPrimaryRecipient( uint256 daiAmount ) external onlyOwnerOr(Role.WITHDRAWAL_MANAGER) override { // Get the current primary recipient. address primaryRecipient = _primaryDaiRecipient; require( primaryRecipient != address(0), "No Dai primary recipient currently set." ); // Transfer the supplied Dai amount to the primary recipient. _transferToken(_DAI, primaryRecipient, daiAmount); } /** * @notice Transfer `etherAmount` Ether to `recipient`. Only the owner may * call this function. * @param recipient address The account to transfer Ether to. * @param etherAmount uint256 The amount of Ether to transfer. */ function withdrawEther( address payable recipient, uint256 etherAmount ) external override onlyOwner { // Transfer the Ether to the specified recipient. _transferEther(recipient, etherAmount); } /** * @notice Transfer `amount` of ERC20 token `token` to `recipient`. Only the * owner may call this function. * @param token ERC20Interface The ERC20 token to transfer. * @param recipient address The account to transfer the tokens to. * @param amount uint256 The amount of tokens to transfer. * @return success - a boolean to indicate if the transfer was successful - note that * unsuccessful ERC20 transfers will usually revert. */ function withdraw( ERC20Interface token, address recipient, uint256 amount ) external onlyOwner override returns (bool success) { // Transfer the token to the specified recipient. success = token.transfer(recipient, amount); } /** * @notice Call account `target`, supplying value `amount` and data `data`. * Only the owner may call this function. * @param target address The account to call. * @param amount uint256 The amount of ether to include as an endowment. * @param data bytes The data to include along with the call. * @return ok and returnData - a boolean to indicate if the call was successful, as well as the * returned data or revert reason. */ function callAny( address payable target, uint256 amount, bytes calldata data ) external onlyOwner override returns (bool ok, bytes memory returnData) { // Call the specified target and supply the specified data. (ok, returnData) = target.call{value:amount}(data); } /** * @notice Set `recipient` as the new primary recipient for USDC withdrawals. * Only the owner may call this function. * @param recipient address The new primary recipient. */ function setPrimaryUSDCRecipient(address recipient) external override onlyOwner { // Set the new primary recipient. _primaryUSDCRecipient = recipient; } /** * @notice Set `recipient` as the new primary recipient for Dai withdrawals. * Only the owner may call this function. * @param recipient address The new primary recipient. */ function setPrimaryDaiRecipient(address recipient) external override onlyOwner { // Set the new primary recipient. _primaryDaiRecipient = recipient; } /** * @notice Pause a currently unpaused role and emit a `RolePaused` event. Only * the owner or the designated pauser may call this function. Also, bear in * mind that only the owner may unpause a role once paused. * @param role The role to pause. */ function pause(Role role) external override onlyOwnerOr(Role.PAUSER) { RoleStatus storage storedRoleStatus = _roles[uint256(role)]; require(!storedRoleStatus.paused, "Role in question is already paused."); storedRoleStatus.paused = true; emit RolePaused(role); } /** * @notice Unpause a currently paused role and emit a `RoleUnpaused` event. * Only the owner may call this function. * @param role The role to pause. */ function unpause(Role role) external override onlyOwner { RoleStatus storage storedRoleStatus = _roles[uint256(role)]; require(storedRoleStatus.paused, "Role in question is already unpaused."); storedRoleStatus.paused = false; emit RoleUnpaused(role); } /** * @notice Set a new account on a given role and emit a `RoleModified` event * if the role holder has changed. Only the owner may call this function. * @param role The role that the account will be set for. * @param account The account to set as the designated role bearer. */ function setRole(Role role, address account) external override onlyOwner { require(account != address(0), "Must supply an account."); _setRole(role, account); } /** * @notice Remove any current role bearer for a given role and emit a * `RoleModified` event if a role holder was previously set. Only the owner * may call this function. * @param role The role that the account will be removed from. */ function removeRole(Role role) external override onlyOwner { _setRole(role, address(0)); } /** * @notice External view function to check whether or not the functionality * associated with a given role is currently paused or not. The owner or the * pauser may pause any given role (including the pauser itself), but only the * owner may unpause functionality. Additionally, the owner may call paused * functions directly. * @param role The role to check the pause status on. * @return paused - a boolean to indicate if the functionality associated with the role * in question is currently paused. */ function isPaused(Role role) external view override returns (bool paused) { paused = _isPaused(role); } /** * @notice External view function to check whether the caller is the current * role holder. * @param role The role to check for. * @return hasRole - a boolean indicating if the caller has the specified role. */ function isRole(Role role) external view override returns (bool hasRole) { hasRole = _isRole(role); } /** * @notice External view function to check whether a "proof" that a given * smart wallet is actually a Dharma Smart Wallet, based on the initial user * signing key, is valid or not. This proof only works when the Dharma Smart * Wallet in question is derived using V1 of the Dharma Smart Wallet Factory. * @param smartWallet address The smart wallet to check. * @param initialUserSigningKey address The initial user signing key supplied * when deriving the smart wallet address - this could be an EOA or a Dharma * key ring address. * @return dharmaSmartWallet - a boolean indicating if the specified smart wallet account is * indeed a smart wallet based on the specified initial user signing key. */ function isDharmaSmartWallet( address smartWallet, address initialUserSigningKey ) external pure override returns (bool dharmaSmartWallet) { dharmaSmartWallet = _isSmartWallet(smartWallet, initialUserSigningKey); } /** * @notice External view function to check the account currently holding the * deposit manager role. The deposit manager can process standard deposit * finalization via `finalizeDaiDeposit` and `finalizeDharmaDaiDeposit`, but * must prove that the recipient is a Dharma Smart Wallet and adhere to the * current deposit size limit. * @return depositManager - the address of the current deposit manager, or the null address if * none is set. */ function getDepositManager() external view override returns (address depositManager) { depositManager = _roles[uint256(Role.DEPOSIT_MANAGER)].account; } /** * @notice External view function to check the account currently holding the * reserve trader role. The reserve trader can trigger trades that utilize * reserves in addition to supplied funds, if any. * @return reserveTrader - the address of the current reserve trader, or the null address if * none is set. */ function getReserveTrader() external view override returns (address reserveTrader) { reserveTrader = _roles[uint256(Role.RESERVE_TRADER)].account; } /** * @notice External view function to check the account currently holding the * withdrawal manager role. The withdrawal manager can transfer USDC to the * "primary recipient" address set by the owner. * @return withdrawalManager - the address of the current withdrawal manager, or the null address * if none is set. */ function getWithdrawalManager() external view override returns ( address withdrawalManager ) { withdrawalManager = _roles[uint256(Role.WITHDRAWAL_MANAGER)].account; } /** * @notice External view function to check the account currently holding the * actioner role. The actioner can submit a generic calls transaction through `execute` * @return actioner - the address of the current actioner, or the null address * if none is set. */ function getActioner() external view override returns ( address actioner ) { actioner = _roles[uint256(Role.ACTIONER)].account; } /** * @notice External view function to check the account currently holding the * pauser role. The pauser can pause any role from taking its standard action, * though the owner will still be able to call the associated function in the * interim and is the only entity able to unpause the given role once paused. * @return pauser - the address of the current pauser, or the null address if none is * set. */ function getPauser() external view override returns (address pauser) { pauser = _roles[uint256(Role.PAUSER)].account; } function getGasReserveRefiller() external view override returns ( address gasReserveRefiller ) { gasReserveRefiller = _roles[uint256(Role.GAS_RESERVE_REFILLER)].account; } /** * @notice External view function to check the address of the current * primary recipient for USDC. * @return recipient - the primary recipient for USDC. */ function getPrimaryUSDCRecipient() external view override returns ( address recipient ) { recipient = _primaryUSDCRecipient; } /** * @notice External view function to check the address of the current * primary recipient for Dai. * @return recipient - the primary recipient for Dai. */ function getPrimaryDaiRecipient() external view override returns ( address recipient ) { recipient = _primaryDaiRecipient; } /** * @notice External view function to check the current implementation * of this contract (i.e. the "logic" for the contract). * @return implementation - the current implementation for this contract. */ function getImplementation() external view override returns ( address implementation ) { (bool ok, bytes memory returnData) = address( 0x2Cf7C0333D9b7F94BbF55B9701227E359F92fD31 ).staticcall(""); require(ok && returnData.length == 32, "Invalid implementation."); implementation = abi.decode(returnData, (address)); } /** * @notice External pure function to get the address of the actual * contract instance (i.e. the "storage" foor this contract). * @return instance - the address of this contract instance. */ function getInstance() external pure override returns (address instance) { instance = address(0x0eFb068354c10c070ddD64a0E8EaF8f054DF7E26); } function getVersion() external pure override returns (uint256 version) { version = _VERSION; } function _grantUniswapRouterApprovalIfNecessary( ERC20Interface token, uint256 amount ) internal { if (token.allowance(address(this), address(_UNISWAP_ROUTER)) < amount) { // Try removing approval first as a workaround for unusual tokens. (bool success, bytes memory data) = address(token).call( abi.encodeWithSelector( token.approve.selector, address(_UNISWAP_ROUTER), uint256(0) ) ); // Grant transfer approval to Uniswap router on behalf of this contract. (success, data) = address(token).call( abi.encodeWithSelector( token.approve.selector, address(_UNISWAP_ROUTER), type(uint256).max ) ); if (!success) { // Some janky tokens only allow setting approval up to current balance. (success, data) = address(token).call( abi.encodeWithSelector( token.approve.selector, address(_UNISWAP_ROUTER), amount ) ); } require( success && (data.length == 0 || abi.decode(data, (bool))), "Token approval for Uniswap router failed." ); } } function _tradeEtherForTokenWithFeeOnTransfer( address tokenReceivedOrUSDCFlag, uint256 etherAmount, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 maximumFeeAmount, uint256 deadline, bool fromReserves, FeeType feeType ) internal returns (uint256 totalTokensBought) { _delegate(V17); } function _tradeEtherForTokenWithFeeOnTransferLegacy( address tokenReceivedOrUSDCFlag, uint256 etherAmount, uint256 quotedTokenAmount, uint256 quotedTokenAmountAfterTransferFee, uint256 deadline, bool fromReserves ) internal returns (uint256 totalTokensBought) { _delegate(V17); } /** * @notice Internal trade function. If token is _TRADE_FOR_USDC_AND_RETAIN_FLAG, * trade for USDC and retain the full output amount by replacing the recipient * ("to" input) on the swapETHForExactTokens call. */ function _tradeExactEtherForToken( address tokenReceivedOrUSDCFlag, uint256 etherAmount, uint256 quotedTokenAmount, uint256 deadline, bool fromReserves, FeeType feeType, uint256 maximumFeeAmount ) internal returns ( uint256 totalTokensBought, uint256 receivedTokenAmount, uint256 retainedAmount ) { // Set swap target destination and token. address destination; address[] memory path = new address[](2); path[0] = _WETH; if (tokenReceivedOrUSDCFlag == _TRADE_FOR_USDC_AND_RETAIN_FLAG) { path[1] = address(_USDC); destination = address(this); } else { path[1] = tokenReceivedOrUSDCFlag; destination = fromReserves ? address(this) : msg.sender; } // Trade Ether for quoted token amount and send to appropriate recipient. uint256[] memory amounts = new uint256[](2); amounts = _UNISWAP_ROUTER.swapExactETHForTokens{value: feeType != FeeType.RECEIVED_ASSET ? etherAmount - maximumFeeAmount : etherAmount }( quotedTokenAmount, path, destination, deadline ); totalTokensBought = amounts[1]; if (feeType == FeeType.RECEIVED_ASSET) { // Retain the lesser of either max fee or bought amount less quoted amount. retainedAmount = maximumFeeAmount.min( totalTokensBought - quotedTokenAmount ); receivedTokenAmount = totalTokensBought - retainedAmount; } else { retainedAmount = maximumFeeAmount; receivedTokenAmount = totalTokensBought; } } function _tradeTokenForEther( ERC20Interface token, uint256 tokenAmount, uint256 tokenAmountAfterTransferFee, uint256 quotedEtherAmount, uint256 deadline, FeeType feeType, uint256 maximumFeeAmount ) internal returns ( uint256 totalEtherBought, uint256 receivedEtherAmount, uint256 retainedAmount ) { // Trade tokens for Ether. uint256 tradeAmount; if (feeType == FeeType.SUPPLIED_ASSET) { tradeAmount = (tokenAmount.min(tokenAmountAfterTransferFee) - maximumFeeAmount); retainedAmount = maximumFeeAmount; } else { tradeAmount = tokenAmount.min(tokenAmountAfterTransferFee); } // Approve Uniswap router to transfer tokens on behalf of this contract. _grantUniswapRouterApprovalIfNecessary(token, tokenAmount); // Establish path from target token to Ether. (address[] memory path, uint256[] memory amounts) = _createPathAndAmounts( address(token), _WETH, false ); // Trade tokens for quoted Ether amount on Uniswap (send to this contract). if (tokenAmount == tokenAmountAfterTransferFee) { amounts = _UNISWAP_ROUTER.swapExactTokensForETH( tradeAmount, quotedEtherAmount, path, address(this), deadline ); totalEtherBought = amounts[1]; } else { uint256 ethBalanceBeforeTrade = address(this).balance; _UNISWAP_ROUTER.swapExactTokensForETHSupportingFeeOnTransferTokens( tradeAmount, quotedEtherAmount, path, address(this), deadline ); totalEtherBought = address(this).balance - ethBalanceBeforeTrade; } if (feeType != FeeType.SUPPLIED_ASSET) { // Retain the lesser of either max fee or bought amount less quoted amount. retainedAmount = maximumFeeAmount.min( totalEtherBought - quotedEtherAmount ); // Receive back the total bought Ether less total retained Ether. receivedEtherAmount = totalEtherBought - retainedAmount; } else { receivedEtherAmount = totalEtherBought; } } /** * @notice Internal trade function. If tokenReceived is _TRADE_FOR_USDC_AND_RETAIN_FLAG, * trade for USDC and retain the full output amount by replacing the recipient * ("to" input) on the swapTokensForExactTokens call. */ function _tradeTokenForToken( address account, ERC20Interface tokenProvided, address tokenReceivedOrUSDCFlag, uint256 tokenProvidedAmount, uint256 quotedTokenReceivedAmount, uint256 maximumFeeAmount, // WETH if routeThroughEther, else tokenReceived uint256 deadline, bool routeThroughEther, FeeType feeType ) internal returns (uint256 totalTokensBought) { uint256 retainedAmount; uint256 receivedAmount; address tokenReceived; // Approve Uniswap router to transfer tokens on behalf of this contract. _grantUniswapRouterApprovalIfNecessary(tokenProvided, tokenProvidedAmount); // Set recipient, swap target token if (tokenReceivedOrUSDCFlag == _TRADE_FOR_USDC_AND_RETAIN_FLAG) { tokenReceived = address(_USDC); } else { tokenReceived = tokenReceivedOrUSDCFlag; } if (routeThroughEther == false) { // Establish direct path between tokens. (address[] memory path, uint256[] memory amounts) = _createPathAndAmounts( address(tokenProvided), tokenReceived, false ); // Trade for the quoted token amount on Uniswap and send to this contract. amounts = _UNISWAP_ROUTER.swapExactTokensForTokens( feeType == FeeType.SUPPLIED_ASSET ? tokenProvidedAmount - maximumFeeAmount : tokenProvidedAmount, quotedTokenReceivedAmount, path, address(this), deadline ); totalTokensBought = amounts[1]; if (feeType == FeeType.RECEIVED_ASSET) { // Retain lesser of either max fee or bought amount less quoted amount. retainedAmount = maximumFeeAmount.min( totalTokensBought - quotedTokenReceivedAmount ); receivedAmount = totalTokensBought - retainedAmount; } else { retainedAmount = maximumFeeAmount; receivedAmount = totalTokensBought; } } else { // Establish path between provided token and WETH. (address[] memory path, uint256[] memory amounts) = _createPathAndAmounts( address(tokenProvided), _WETH, false ); // Trade all provided tokens for WETH on Uniswap and send to this contract. amounts = _UNISWAP_ROUTER.swapExactTokensForTokens( feeType == FeeType.SUPPLIED_ASSET ? tokenProvidedAmount - maximumFeeAmount : tokenProvidedAmount, feeType == FeeType.ETHER ? maximumFeeAmount : 1, path, address(this), deadline ); retainedAmount = amounts[1]; // Establish path between WETH and received token. (path, amounts) = _createPathAndAmounts( _WETH, tokenReceived, false ); // Trade bought WETH (less fee) for received token, send to this contract. amounts = _UNISWAP_ROUTER.swapExactTokensForTokens( feeType == FeeType.ETHER ? retainedAmount - maximumFeeAmount : retainedAmount, quotedTokenReceivedAmount, path, address(this), deadline ); totalTokensBought = amounts[1]; if (feeType == FeeType.RECEIVED_ASSET) { // Retain lesser of either max fee or bought amount less quoted amount. retainedAmount = maximumFeeAmount.min( totalTokensBought - quotedTokenReceivedAmount ); receivedAmount = totalTokensBought - retainedAmount; } else { retainedAmount = maximumFeeAmount; receivedAmount = totalTokensBought; } } _emitTrade( account, address(tokenProvided), tokenReceivedOrUSDCFlag, feeType == FeeType.ETHER ? _WETH : (feeType == FeeType.RECEIVED_ASSET ? tokenReceived : address(tokenProvided) ), tokenProvidedAmount, receivedAmount, retainedAmount ); if ( account != address(this) && tokenReceivedOrUSDCFlag != _TRADE_FOR_USDC_AND_RETAIN_FLAG ) { _transferToken(ERC20Interface(tokenReceived), account, receivedAmount); } } /** * @notice Internal trade function. If tokenReceived is _TRADE_FOR_USDC_AND_RETAIN_FLAG, * trade for USDC and retain the full output amount by replacing the recipient * ("to" input) on the swapTokensForExactTokens call. */ function _tradeTokenForTokenLegacy( address account, ERC20Interface tokenProvided, address tokenReceivedOrUSDCFlag, uint256 tokenProvidedAmount, uint256 quotedTokenReceivedAmount, uint256 deadline, bool routeThroughEther ) internal returns (uint256 totalTokensSold) { uint256 retainedAmount; address tokenReceived; address recipient; // Approve Uniswap router to transfer tokens on behalf of this contract. _grantUniswapRouterApprovalIfNecessary(tokenProvided, tokenProvidedAmount); // Set recipient, swap target token if (tokenReceivedOrUSDCFlag == _TRADE_FOR_USDC_AND_RETAIN_FLAG) { recipient = address(this); tokenReceived = address(_USDC); } else { recipient = account; tokenReceived = tokenReceivedOrUSDCFlag; } if (routeThroughEther == false) { // Establish direct path between tokens. (address[] memory path, uint256[] memory amounts) = _createPathAndAmounts( address(tokenProvided), tokenReceived, false ); // Trade for the quoted token amount on Uniswap and send to recipient. amounts = _UNISWAP_ROUTER.swapTokensForExactTokens( quotedTokenReceivedAmount, tokenProvidedAmount, path, recipient, deadline ); totalTokensSold = amounts[0]; retainedAmount = tokenProvidedAmount - totalTokensSold; } else { // Establish path between provided token and WETH. (address[] memory path, uint256[] memory amounts) = _createPathAndAmounts( address(tokenProvided), _WETH, false ); // Trade all provided tokens for WETH on Uniswap and send to this contract. amounts = _UNISWAP_ROUTER.swapExactTokensForTokens( tokenProvidedAmount, 0, path, address(this), deadline ); retainedAmount = amounts[1]; // Establish path between WETH and received token. (path, amounts) = _createPathAndAmounts( _WETH, tokenReceived, false ); // Trade bought WETH for received token on Uniswap and send to recipient. amounts = _UNISWAP_ROUTER.swapTokensForExactTokens( quotedTokenReceivedAmount, retainedAmount, path, recipient, deadline ); totalTokensSold = amounts[0]; retainedAmount = retainedAmount - totalTokensSold; } _emitTrade( account, address(tokenProvided), tokenReceivedOrUSDCFlag, routeThroughEther ? _WETH : address(tokenProvided), tokenProvidedAmount, quotedTokenReceivedAmount, retainedAmount ); } struct TradeTokenForTokenWithFeeOnTransferArgs { address account; ERC20Interface tokenProvided; address tokenReceivedOrUSDCFlag; uint256 tokenProvidedAmount; uint256 tokenProvidedAmountAfterTransferFee; uint256 quotedTokenReceivedAmount; uint256 quotedTokenReceivedAmountAfterTransferFee; uint256 maximumFeeAmount; uint256 deadline; bool routeThroughEther; FeeType feeType; } /** * @notice Internal trade function for cases where one of the tokens in * question levies a transfer fee. If tokenReceived is * _TRADE_FOR_USDC_AND_RETAIN_FLAG, trade for USDC and retain the full output * amount by replacing the recipient ("to" input) on the * swapTokensForExactTokens call. */ function _tradeTokenForTokenWithFeeOnTransfer( TradeTokenForTokenWithFeeOnTransferArgs memory args ) internal returns (uint256 totalTokensBought) { ERC20Interface tokenReceived = ( args.tokenReceivedOrUSDCFlag == _TRADE_FOR_USDC_AND_RETAIN_FLAG ? ERC20Interface(_USDC) : ERC20Interface(args.tokenReceivedOrUSDCFlag) ); // Approve Uniswap router to transfer tokens on behalf of this contract. _grantUniswapRouterApprovalIfNecessary( args.tokenProvided, args.tokenProvidedAmountAfterTransferFee ); { // Scope to avoid stack too deep error. // Establish path between tokens. (address[] memory path, ) = _createPathAndAmounts( address(args.tokenProvided), address(tokenReceived), args.routeThroughEther ); // Get this contract's balance in the output token prior to the trade. uint256 priorReserveBalanceOfReceivedToken = tokenReceived.balanceOf( address(this) ); // Trade for the quoted token amount on Uniswap and send to this contract. _UNISWAP_ROUTER.swapExactTokensForTokensSupportingFeeOnTransferTokens( args.feeType == FeeType.SUPPLIED_ASSET ? args.tokenProvidedAmountAfterTransferFee - args.maximumFeeAmount : args.tokenProvidedAmountAfterTransferFee, args.quotedTokenReceivedAmount, path, address(this), args.deadline ); totalTokensBought = tokenReceived.balanceOf(address(this)) - priorReserveBalanceOfReceivedToken; } uint256 receivedAmountAfterTransferFee; if ( args.account != address(this) && args.tokenReceivedOrUSDCFlag != _TRADE_FOR_USDC_AND_RETAIN_FLAG ) { { // Get the receiver's balance prior to the transfer. uint256 priorRecipientBalanceOfReceivedToken = tokenReceived.balanceOf( args.account ); // Transfer the received tokens (less the fee) to the recipient. _transferToken( tokenReceived, args.account, args.feeType == FeeType.RECEIVED_ASSET ? totalTokensBought - args.maximumFeeAmount : totalTokensBought ); receivedAmountAfterTransferFee = tokenReceived.balanceOf(args.account) - priorRecipientBalanceOfReceivedToken; } // Ensure that sufficient tokens were returned to the user. require( receivedAmountAfterTransferFee >= args.quotedTokenReceivedAmountAfterTransferFee, "Received token amount after transfer fee is less than quoted amount." ); } else { receivedAmountAfterTransferFee = args.feeType == FeeType.RECEIVED_ASSET ? totalTokensBought - args.maximumFeeAmount : totalTokensBought; } _emitTrade( args.account, address(args.tokenProvided), args.tokenReceivedOrUSDCFlag, args.feeType == FeeType.RECEIVED_ASSET ? address(tokenReceived) : address(args.tokenProvided), args.tokenProvidedAmount, receivedAmountAfterTransferFee, args.maximumFeeAmount ); } /** * @notice Internal trade function for cases where one of the tokens in * question levies a transfer fee. If tokenReceived is * _TRADE_FOR_USDC_AND_RETAIN_FLAG, trade for USDC and retain the full output * amount by replacing the recipient ("to" input) on the * swapTokensForExactTokens call. */ function _tradeTokenForTokenWithFeeOnTransferLegacy( address account, ERC20Interface tokenProvided, address tokenReceivedOrUSDCFlag, uint256 tokenProvidedAmount, uint256 tokenProvidedAmountAfterTransferFee, uint256 quotedTokenReceivedAmount, uint256 quotedTokenReceivedAmountAfterTransferFee, uint256 deadline, bool routeThroughEther ) internal returns (uint256 totalTokensBought) { uint256 retainedAmount; uint256 receivedAmountAfterTransferFee; ERC20Interface tokenReceived; // Approve Uniswap router to transfer tokens on behalf of this contract. _grantUniswapRouterApprovalIfNecessary( tokenProvided, tokenProvidedAmountAfterTransferFee ); { // Scope to avoid stack too deep error. address recipient; // Set recipient, swap target token if (tokenReceivedOrUSDCFlag == _TRADE_FOR_USDC_AND_RETAIN_FLAG) { recipient = address(this); tokenReceived = ERC20Interface(_USDC); } else { recipient = account; tokenReceived = ERC20Interface(tokenReceivedOrUSDCFlag); } // Establish path between tokens. (address[] memory path, ) = _createPathAndAmounts( address(tokenProvided), address(tokenReceived), routeThroughEther ); // Get this contract's balance in the output token prior to the trade. uint256 priorReserveBalanceOfReceivedToken = tokenReceived.balanceOf( address(this) ); // Trade for the quoted token amount on Uniswap and send to this contract. _UNISWAP_ROUTER.swapExactTokensForTokensSupportingFeeOnTransferTokens( tokenProvidedAmountAfterTransferFee, quotedTokenReceivedAmount, path, address(this), deadline ); totalTokensBought = tokenReceived.balanceOf(address(this)) - priorReserveBalanceOfReceivedToken; retainedAmount = totalTokensBought - quotedTokenReceivedAmount; // Get the receiver's balance prior to the transfer. uint256 priorRecipientBalanceOfReceivedToken = tokenReceived.balanceOf( recipient ); // Transfer the received tokens to the recipient. _transferToken(tokenReceived, recipient, quotedTokenReceivedAmount); receivedAmountAfterTransferFee = tokenReceived.balanceOf(recipient) - priorRecipientBalanceOfReceivedToken; // Ensure that sufficient tokens were returned to the user. require( receivedAmountAfterTransferFee >= quotedTokenReceivedAmountAfterTransferFee, "Received token amount after transfer fee is less than quoted amount." ); } _emitTrade( account, address(tokenProvided), tokenReceivedOrUSDCFlag, address(tokenReceived), tokenProvidedAmount, receivedAmountAfterTransferFee, retainedAmount ); } /** * @notice Internal function to set a new account on a given role and emit a * `RoleModified` event if the role holder has changed. * @param role The role that the account will be set for. Permitted roles are * deposit manager (0), adjuster (1), and pauser (2). * @param account The account to set as the designated role bearer. */ function _setRole(Role role, address account) internal { RoleStatus storage storedRoleStatus = _roles[uint256(role)]; if (account != storedRoleStatus.account) { storedRoleStatus.account = account; emit RoleModified(role, account); } } function _emitTrade( address account, address suppliedAsset, address receivedAsset, address retainedAsset, uint256 suppliedAmount, uint256 receivedAmount, uint256 retainedAmount ) internal { emit Trade( account, suppliedAsset, receivedAsset, retainedAsset, suppliedAmount, receivedAmount, retainedAmount ); } function _fireTradeEvent( bool fromReserves, bool supplyingEther, bool feeInEther, address token, uint256 suppliedAmount, uint256 receivedAmount, uint256 retainedAmount ) internal { emit Trade( fromReserves ? address(this) : msg.sender, supplyingEther ? address(0) : token, supplyingEther ? token : address(0), feeInEther ? address(0) : (token == _TRADE_FOR_USDC_AND_RETAIN_FLAG ? address(_USDC) : token), suppliedAmount, receivedAmount, retainedAmount ); } /** * @notice Internal view function to check whether the caller is the current * role holder. * @param role The role to check for. * @return hasRole - a boolean indicating if the caller has the specified role. */ function _isRole(Role role) internal view returns (bool hasRole) { hasRole = msg.sender == _roles[uint256(role)].account; } /** * @notice Internal view function to check whether the given role is paused or * not. * @param role The role to check for. * @return paused - a boolean indicating if the specified role is paused or not. */ function _isPaused(Role role) internal view returns (bool paused) { paused = _roles[uint256(role)].paused; } /** * @notice Internal view function to enforce that the given initial user signing * key resolves to the given smart wallet when deployed through the Dharma Smart * Wallet Factory V1. (staging version) * @param smartWallet address The smart wallet. * @param initialUserSigningKey address The initial user signing key. */ function _isSmartWallet( address smartWallet, address initialUserSigningKey ) internal pure returns (bool) { // Derive the keccak256 hash of the smart wallet initialization code. bytes32 initCodeHash = keccak256( abi.encodePacked( _WALLET_CREATION_CODE_HEADER, initialUserSigningKey, _WALLET_CREATION_CODE_FOOTER ) ); // Attempt to derive a smart wallet address that matches the one provided. address target; for (uint256 nonce = 0; nonce < 10; nonce++) { target = address( // derive the target deployment address. uint160( // downcast to match the address type. uint256( // cast to uint to truncate upper digits. keccak256( // compute CREATE2 hash using all inputs. abi.encodePacked( // pack all inputs to the hash together. _CREATE2_HEADER, // pass in control character + factory address. nonce, // pass in current nonce as the salt. initCodeHash // pass in hash of contract creation code. ) ) ) ) ); // Exit early if the provided smart wallet matches derived target address. if (target == smartWallet) { return true; } // Otherwise, increment the nonce and derive a new salt. nonce++; } // Explicity recognize no target was found matching provided smart wallet. return false; } function _transferToken(ERC20Interface token, address to, uint256 amount) internal { (bool success, bytes memory data) = address(token).call( abi.encodeWithSelector(token.transfer.selector, to, amount) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "Transfer out failed." ); } function _transferEther(address recipient, uint256 etherAmount) internal { // Send quoted Ether amount to recipient and revert with reason on failure. (bool ok, ) = recipient.call{value:etherAmount}(""); if (!ok) { assembly { returndatacopy(0, 0, returndatasize()) revert(0, returndatasize()) } } } function _transferInToken(ERC20Interface token, address from, uint256 amount) internal { (bool success, bytes memory data) = address(token).call( abi.encodeWithSelector(token.transferFrom.selector, from, address(this), amount) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "Transfer in failed." ); } function _ensureSmartWallet( address smartWallet, address initialUserSigningKey ) internal pure { require( _isSmartWallet(smartWallet, initialUserSigningKey), "Could not resolve smart wallet using provided signing key." ); } function _createPathAndAmounts( address start, address end, bool routeThroughEther ) internal pure returns (address[] memory, uint256[] memory) { uint256 pathLength = routeThroughEther ? 3 : 2; address[] memory path = new address[](pathLength); path[0] = start; if (routeThroughEther) { path[1] = _WETH; } path[pathLength - 1] = end; return (path, new uint256[](pathLength)); } function _ensureNoEtherFeeTypeWhenNotRouted( bool routeThroughEther, FeeType feeType ) internal pure { require( routeThroughEther || feeType != FeeType.ETHER, "Cannot take token-for-token fee in Ether unless routed through Ether." ); } function _ensureNoEtherFee(FeeType feeType) internal pure { require( feeType != FeeType.ETHER, "Cannot take token-for-token fee in Ether with fee on transfer." ); } function _delegate(address implementation) private { assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @notice Modifier that throws if called by any account other than the owner * or the supplied role, or if the caller is not the owner and the role in * question is paused. * @param role The role to require unless the caller is the owner. */ modifier onlyOwnerOr(Role role) { if (!isOwner()) { require(_isRole(role), "Caller does not have a required role."); require(!_isPaused(role), "Role in question is currently paused."); } _; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"actionRegistryAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"string","name":"revertReason","type":"string"}],"name":"CallFailure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"rolledBack","type":"bool"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"CallSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EtherReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"etherAmount","type":"uint256"}],"name":"GasReserveRefilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"RoleModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"}],"name":"RolePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"}],"name":"RoleUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"suppliedAsset","type":"address"},{"indexed":false,"internalType":"address","name":"receivedAsset","type":"address"},{"indexed":false,"internalType":"address","name":"retainedAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"suppliedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"recievedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"retainedAmount","type":"uint256"}],"name":"Trade","type":"event"},{"inputs":[],"name":"_ACTION_REGISTRY","outputs":[{"internalType":"contract IActionRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint96","name":"value","type":"uint96"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITypes.Call[]","name":"calls","type":"tuple[]"}],"name":"_execute","outputs":[{"components":[{"internalType":"bool","name":"ok","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct ITypes.CallReturn[]","name":"callResults","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint96","name":"value","type":"uint96"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITypes.Call[]","name":"calls","type":"tuple[]"}],"name":"_simulate","outputs":[{"components":[{"internalType":"bool","name":"ok","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct ITypes.CallReturn[]","name":"callResults","type":"tuple[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"target","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"callAny","outputs":[{"internalType":"bool","name":"ok","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelOwnershipTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint96","name":"value","type":"uint96"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITypes.Call[]","name":"calls","type":"tuple[]"}],"name":"execute","outputs":[{"internalType":"bool[]","name":"ok","type":"bool[]"},{"internalType":"bytes[]","name":"returnData","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"smartWallet","type":"address"},{"internalType":"address","name":"initialUserSigningKey","type":"address"},{"internalType":"uint256","name":"etherAmount","type":"uint256"}],"name":"finalizeEtherDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"smartWallet","type":"address"},{"internalType":"address","name":"initialUserSigningKey","type":"address"},{"internalType":"contract ERC20Interface","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"finalizeTokenDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getActioner","outputs":[{"internalType":"address","name":"actioner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDepositManager","outputs":[{"internalType":"address","name":"depositManager","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGasReserveRefiller","outputs":[{"internalType":"address","name":"gasReserveRefiller","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getImplementation","outputs":[{"internalType":"address","name":"implementation","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInstance","outputs":[{"internalType":"address","name":"instance","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getPauser","outputs":[{"internalType":"address","name":"pauser","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrimaryDaiRecipient","outputs":[{"internalType":"address","name":"recipient","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrimaryUSDCRecipient","outputs":[{"internalType":"address","name":"recipient","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserveTrader","outputs":[{"internalType":"address","name":"reserveTrader","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVersion","outputs":[{"internalType":"uint256","name":"version","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getWithdrawalManager","outputs":[{"internalType":"address","name":"withdrawalManager","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"smartWallet","type":"address"},{"internalType":"address","name":"initialUserSigningKey","type":"address"}],"name":"isDharmaSmartWallet","outputs":[{"internalType":"bool","name":"dharmaSmartWallet","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"}],"name":"isPaused","outputs":[{"internalType":"bool","name":"paused","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"}],"name":"isRole","outputs":[{"internalType":"bool","name":"hasRole","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"etherAmount","type":"uint256"}],"name":"refillGasReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"}],"name":"removeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"setPrimaryDaiRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"setPrimaryUSDCRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"},{"internalType":"address","name":"account","type":"address"}],"name":"setRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint96","name":"value","type":"uint96"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ITypes.Call[]","name":"calls","type":"tuple[]"}],"name":"simulate","outputs":[{"internalType":"bool[]","name":"ok","type":"bool[]"},{"internalType":"bytes[]","name":"returnData","type":"bytes[]"},{"internalType":"bool","name":"validCalls","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"quotedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeEtherForTokenSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"etherAmountFromReserves","type":"uint256"},{"internalType":"uint256","name":"quotedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeEtherForTokenUsingReservesSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"etherAmountFromReserves","type":"uint256"},{"internalType":"uint256","name":"quotedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenAmountAfterTransferFee","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeEtherForTokenUsingReservesWithFeeOnTransferSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"quotedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenAmountAfterTransferFee","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tradeEtherForTokenWithFeeOnTransfer","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"quotedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenAmountAfterTransferFee","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeEtherForTokenWithFeeOnTransferSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"etherAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenAmountAfterTransferFee","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tradeEtherForTokenWithFeeOnTransferUsingEtherizer","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"token","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"quotedEtherAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeTokenForEtherSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalEtherBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"token","type":"address"},{"internalType":"uint256","name":"tokenAmountFromReserves","type":"uint256"},{"internalType":"uint256","name":"quotedEtherAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeTokenForEtherUsingReservesSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalEtherBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"token","type":"address"},{"internalType":"uint256","name":"tokenAmountFromReserves","type":"uint256"},{"internalType":"uint256","name":"quotedEtherAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeTokenForEtherUsingReservesWithFeeOnTransferSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalEtherBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"token","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"quotedEtherAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tradeTokenForEtherWithFeeOnTransfer","outputs":[{"internalType":"uint256","name":"totalEtherBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"token","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"quotedEtherAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeTokenForEtherWithFeeOnTransferSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalEtherBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"tokenProvided","type":"address"},{"internalType":"address","name":"tokenReceived","type":"address"},{"internalType":"uint256","name":"tokenProvidedAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenReceivedAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"routeThroughEther","type":"bool"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeTokenForTokenSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"tokenProvidedFromReserves","type":"address"},{"internalType":"address","name":"tokenReceived","type":"address"},{"internalType":"uint256","name":"tokenProvidedAmountFromReserves","type":"uint256"},{"internalType":"uint256","name":"quotedTokenReceivedAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"routeThroughEther","type":"bool"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeTokenForTokenUsingReservesSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"tokenProvidedFromReserves","type":"address"},{"internalType":"address","name":"tokenReceived","type":"address"},{"internalType":"uint256","name":"tokenProvidedAmountFromReserves","type":"uint256"},{"internalType":"uint256","name":"quotedTokenReceivedAmount","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"routeThroughEther","type":"bool"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeTokenForTokenUsingReservesWithFeeOnTransferSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"tokenProvided","type":"address"},{"internalType":"address","name":"tokenReceived","type":"address"},{"internalType":"uint256","name":"tokenProvidedAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenReceivedAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenReceivedAmountAfterTransferFee","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"routeThroughEther","type":"bool"}],"name":"tradeTokenForTokenWithFeeOnTransfer","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"tokenProvided","type":"address"},{"internalType":"address","name":"tokenReceived","type":"address"},{"internalType":"uint256","name":"tokenProvidedAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenReceivedAmount","type":"uint256"},{"internalType":"uint256","name":"quotedTokenReceivedAmountAfterTransferFee","type":"uint256"},{"internalType":"uint256","name":"maximumFeeAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"routeThroughEther","type":"bool"},{"internalType":"enum DharmaTradeReserveV19Interface.FeeType","name":"feeType","type":"uint8"}],"name":"tradeTokenForTokenWithFeeOnTransferSpecifyingFee","outputs":[{"internalType":"uint256","name":"totalTokensBought","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum DharmaTradeReserveV19Interface.Role","name":"role","type":"uint8"}],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ERC20Interface","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"daiAmount","type":"uint256"}],"name":"withdrawDaiToPrimaryRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"etherAmount","type":"uint256"}],"name":"withdrawEther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdcAmount","type":"uint256"}],"name":"withdrawUSDCToPrimaryRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162005e2f38038062005e2f833981016040819052620000349162000093565b600080546001600160a01b03191632178082556040516001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360601b6001600160601b031916608052620000c3565b600060208284031215620000a5578081fd5b81516001600160a01b0381168114620000bc578182fd5b9392505050565b60805160601c615d3f620000f060003960008181610b6d01528181610ff401526114830152615d3f6000f3fe6080604052600436106103385760003560e01c80638f32d59b116101ab578063c6102aa8116100f7578063eb68b08a11610095578063f2fde38b1161006f578063f2fde38b14610946578063f495018714610966578063f816c0fa14610986578063f97086f6146109a657610378565b8063eb68b08a146108f1578063edf07f1514610906578063f2e12a391461092657610378565b8063d9caed12116100d1578063d9caed1214610887578063dab41d0d146108a7578063de7b5d14146108c7578063e20ed9d2146108dc57610378565b8063c6102aa814610832578063c90418b414610847578063cef0a6041461086757610378565b8063afd6116b11610164578063bb6033201161013e578063bb603320146107b2578063bc61e733146107d2578063c21e4e42146107f2578063c54d559e1461081257610378565b8063afd6116b1461075c578063b1f2aa6714610789578063badafb37146107a457610378565b80638f32d59b146106b25780639b86f0ef146106c7578063a0a6d75f146106e7578063a735559614610707578063aaf10f4214610727578063aeed28611461073c57610378565b8063329504da116102855780637008b5481161022357806378a967aa116101fd57806378a967aa1461064857806379ba5097146106685780638218a8e91461067d5780638da5cb5b1461069d57610378565b80637008b548146105d657806372b272eb146105eb5780637787c5871461061957610378565b8063522f68151161025f578063522f6815146105545780635ce4a04914610574578063618fdbb0146105895780636b309696146105a957610378565b8063329504da1461050c5780633efa667e146105215780634d0757eb1461054157610378565b806321a012ec116102f2578063301c7e5d116102cc578063301c7e5d146104a25780633059d1d3146104c257806331ab6d2a146104d757806331ae1f02146104f757610378565b806321a012ec1461044d57806323452b9c1461046d5780632e5cd5f31461048257610378565b806263f2fb1461037d5780630d8e6e2c1461039f57806312e6bf6a146103ca57806312fd415a146103f8578063153f92eb1461041857806318b93e461461043a57610378565b36610378577f1e57e3bb474320be3d2c77138f75b7c3941292d647f5f9634e33a8e94e0e069b333460405161036e929190614df1565b60405180910390a1005b600080fd5b34801561038957600080fd5b5061039d610398366004614320565b6109c6565b005b3480156103ab57600080fd5b506103b4610a15565b6040516103c191906156be565b60405180910390f35b3480156103d657600080fd5b506103ea6103e53660046143c3565b610a1a565b6040516103c19291906150b7565b34801561040457600080fd5b506103b461041336600461459c565b610aad565b34801561042457600080fd5b5061042d610b6b565b6040516103c19190614d5b565b6103b461044836600461459c565b610b8f565b34801561045957600080fd5b506103b46104683660046149ef565b610bb8565b34801561047957600080fd5b5061039d610c3c565b34801561048e57600080fd5b5061039d61049d366004614358565b610c72565b3480156104ae57600080fd5b5061039d6104bd366004614af9565b610ce5565b3480156104ce57600080fd5b5061042d610dc2565b3480156104e357600080fd5b506103b46104f236600461459c565b610dd1565b34801561050357600080fd5b5061042d610e3f565b34801561051857600080fd5b5061042d610e65565b34801561052d57600080fd5b506103b461053c366004614a6f565b610e74565b6103b461054f366004614508565b610ea0565b34801561056057600080fd5b5061039d61056f366004614398565b610efa565b34801561058057600080fd5b5061042d610f2c565b34801561059557600080fd5b506103b46105a43660046144ce565b610f38565b3480156105b557600080fd5b506105c96105c4366004614446565b610f5f565b6040516103c1919061506b565b3480156105e257600080fd5b5061042d610f72565b3480156105f757600080fd5b5061060b6106063660046147af565b610f7e565b6040516103c1929190614e43565b34801561062557600080fd5b50610639610634366004614741565b61147c565b6040516103c193929190614e68565b34801561065457600080fd5b5061039d610663366004614320565b6117a4565b34801561067457600080fd5b5061039d6117ea565b34801561068957600080fd5b506103b4610698366004614559565b611870565b3480156106a957600080fd5b5061042d611898565b3480156106be57600080fd5b506105c96118a7565b3480156106d357600080fd5b506103b46106e236600461459c565b6118b8565b3480156106f357600080fd5b506103b46107023660046149ef565b61195f565b34801561071357600080fd5b506103b46107223660046145f5565b611a52565b34801561073357600080fd5b5061042d611abe565b34801561074857600080fd5b5061039d61075736600461447e565b611b77565b34801561076857600080fd5b5061077c6107773660046147af565b611bec565b6040516103c19190614ea0565b34801561079557600080fd5b506103b461044836600461459c565b6103b46105a43660046144ce565b3480156107be57600080fd5b506105c96107cd366004614af9565b611dda565b3480156107de57600080fd5b506105c96107ed366004614af9565b611deb565b3480156107fe57600080fd5b5061077c61080d3660046147af565b611df6565b34801561081e57600080fd5b5061039d61082d366004614b73565b611fed565b34801561083e57600080fd5b5061042d612093565b34801561085357600080fd5b506103b46108623660046149ef565b61209e565b34801561087357600080fd5b5061039d610882366004614b73565b6120c6565b34801561089357600080fd5b506105c96108a236600461496a565b612167565b3480156108b357600080fd5b5061039d6108c2366004614af9565b61220d565b3480156108d357600080fd5b5061042d61223f565b3480156108e857600080fd5b5061042d612257565b3480156108fd57600080fd5b5061042d612263565b34801561091257600080fd5b5061039d610921366004614af9565b61226f565b34801561093257600080fd5b5061039d610941366004614b13565b612389565b34801561095257600080fd5b5061039d610961366004614320565b6123dd565b34801561097257600080fd5b506103b461098136600461459c565b612449565b34801561099257600080fd5b5061039d6109a1366004614b73565b6124b6565b3480156109b257600080fd5b506103b46109c136600461497e565b612568565b6109ce6118a7565b6109f35760405162461bcd60e51b81526004016109ea906153a5565b60405180910390fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b601390565b60006060610a266118a7565b610a425760405162461bcd60e51b81526004016109ea906153a5565b856001600160a01b0316858585604051610a5d929190614ce6565b60006040518083038185875af1925050503d8060008114610a9a576040519150601f19603f3d011682016040523d82523d6000602084013e610a9f565b606091505b509097909650945050505050565b60006003610ab96118a7565b610b0857610ac681612592565b610ae25760405162461bcd60e51b81526004016109ea906152be565b610aeb816125da565b15610b085760405162461bcd60e51b81526004016109ea90615527565b600080610b248a610b1a8b60016157b2565b8b8b8a8a8d612621565b91955092509050610b5e6001600080886002811115610b5357634e487b7160e01b600052602160045260246000fd5b14158d8d8787612873565b5050509695505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610bae73f1209998bd17eae301a97e3cf7ec17df580e796461291d565b9695505050505050565b60006003610bc46118a7565b610c1357610bd181612592565b610bed5760405162461bcd60e51b81526004016109ea906152be565b610bf6816125da565b15610c135760405162461bcd60e51b81526004016109ea90615527565b610c1d8484612941565b610c2e308b8b8b8b8b8b8b8b612989565b9a9950505050505050505050565b610c446118a7565b610c605760405162461bcd60e51b81526004016109ea906153a5565b600180546001600160a01b0319169055565b6000610c7c6118a7565b610ccb57610c8981612592565b610ca55760405162461bcd60e51b81526004016109ea906152be565b610cae816125da565b15610ccb5760405162461bcd60e51b81526004016109ea90615527565b610cd58484612ef3565b610cdf8483612f19565b50505050565b610ced6118a7565b610d095760405162461bcd60e51b81526004016109ea906153a5565b600060026000836006811115610d2f57634e487b7160e01b600052602160045260246000fd5b815260208101919091526040016000208054909150600160a01b900460ff16610d6a5760405162461bcd60e51b81526004016109ea906154e2565b805460ff60a01b19168155816006811115610d9557634e487b7160e01b600052602160045260246000fd5b6040517fd9ff16dcccc040d408ddf47191ae2d5313510993b245b3a7ccfb0258a4401d7890600090a25050565b6004546001600160a01b031690565b6000610dde873388612f87565b600080610df089898a8a89898c612621565b91945092509050610e2960008080876002811115610e1e57634e487b7160e01b600052602160045260246000fd5b14158c8c8787612873565b610e333383612f19565b50509695505050505050565b6000600281805b81526020810191909152604001600020546001600160a01b0316919050565b6003546001600160a01b031690565b6000610e9373f1209998bd17eae301a97e3cf7ec17df580e796461291d565b9998505050505050505050565b6000806000610eb5883489886000898c613077565b91945092509050610eef6000600180876002811115610ee457634e487b7160e01b600052602160045260246000fd5b14158b348787612873565b505095945050505050565b610f026118a7565b610f1e5760405162461bcd60e51b81526004016109ea906153a5565b610f288282612f19565b5050565b60006002816005610e46565b6000610f5773f1209998bd17eae301a97e3cf7ec17df580e796461291d565b949350505050565b6000610f6b8383613329565b9392505050565b60006002816004610e46565b6060806006610f8b6118a7565b610fda57610f9881612592565b610fb45760405162461bcd60e51b81526004016109ea906152be565b610fbd816125da565b15610fda5760405162461bcd60e51b81526004016109ea90615527565b60405163c7cbc79960e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c7cbc79990611029908890600401614feb565b60206040518083038186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611079919061494e565b9050806110985760405162461bcd60e51b81526004016109ea9061512f565b84516001600160401b038111156110bf57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156110e8578160200160208202803683370190505b50935084516001600160401b0381111561111257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561114557816020015b60608152602001906001900390816111305790505b506007805464ffffffff0019166472b272eb001790556040519093506000908190309063610f272160e11b9061117f908a90602401614feb565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111bd9190614cf6565b6000604051808303816000865af19150503d80600081146111fa576040519150601f19603f3d011682016040523d82523d6000602084013e6111ff565b606091505b509150915081611218576007805464ffffffff00191690555b60008180602001905181019061122e9190614659565b905060005b815181101561147157600089828151811061125e57634e487b7160e01b600052603260045260246000fd5b6020026020010151905082828151811061128857634e487b7160e01b600052603260045260246000fd5b6020026020010151600001518983815181106112b457634e487b7160e01b600052603260045260246000fd5b6020026020010190151590811515815250508282815181106112e657634e487b7160e01b600052603260045260246000fd5b60200260200101516020015188838151811061131257634e487b7160e01b600052603260045260246000fd5b602002602001018190525082828151811061133d57634e487b7160e01b600052603260045260246000fd5b602002602001015160000151156113d3577f26f13c2c104b2a1b3f0b1c6232d84f2bba70d231216636c3ceeebea631eb97dd8515826000015183602001516001600160601b031684604001518787815181106113a957634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516040516113c6959493929190615076565b60405180910390a161145e565b7f2007dedc5d6ba6b20b13bb9cbff9121300b36978bbac6fbbc5ccadaa1ff6c668816000015182602001516001600160601b0316836040015161144087878151811061142f57634e487b7160e01b600052603260045260246000fd5b602002602001015160200151613426565b6040516114509493929190614e0a565b60405180910390a150611471565b50806114698161580d565b915050611233565b505050505050915091565b60608060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c7cbc79986866040518363ffffffff1660e01b81526004016114cf929190614f13565b60206040518083038186803b1580156114e757600080fd5b505afa1580156114fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151f919061494e565b9050836001600160401b0381111561154757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611570578160200160208202803683370190505b509250836001600160401b0381111561159957634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156115cc57816020015b60608152602001906001900390816115b75790505b5091506000306001600160a01b031663afd6116b60e01b87876040516024016115f6929190614f13565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516116349190614cf6565b6000604051808303816000865af19150503d8060008114611671576040519150601f19603f3d011682016040523d82523d6000602084013e611676565b606091505b509150506000818060200190518101906116909190614659565b905060005b815181101561179a578181815181106116be57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001518682815181106116ea57634e487b7160e01b600052603260045260246000fd5b60200260200101901515908115158152505081818151811061171c57634e487b7160e01b600052603260045260246000fd5b60200260200101516020015185828151811061174857634e487b7160e01b600052603260045260246000fd5b602002602001018190525081818151811061177357634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516117885761179a565b806117928161580d565b915050611695565b5050509250925092565b6117ac6118a7565b6117c85760405162461bcd60e51b81526004016109ea906153a5565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146118145760405162461bcd60e51b81526004016109ea9061533a565b600180546001600160a01b03191690556000805460405133926001600160a01b03909216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b03191633179055565b600061188f73f1209998bd17eae301a97e3cf7ec17df580e796461291d565b95945050505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b600060036118c46118a7565b611913576118d181612592565b6118ed5760405162461bcd60e51b81526004016109ea906152be565b6118f6816125da565b156119135760405162461bcd60e51b81526004016109ea90615527565b6000806119268a8a8a8960018a8d613077565b91955092509050610b5e6001808088600281111561195457634e487b7160e01b600052602160045260246000fd5b14158d8d878d612873565b6000600361196b6118a7565b6119ba5761197881612592565b6119945760405162461bcd60e51b81526004016109ea906152be565b61199d816125da565b156119ba5760405162461bcd60e51b81526004016109ea90615527565b6119c383613671565b610c2e604051806101600160405280306001600160a01b031681526020018c6001600160a01b031681526020018b6001600160a01b031681526020018a81526020018a81526020018981526020018a81526020018881526020018781526020018615158152602001856002811115611a4b57634e487b7160e01b600052602160045260246000fd5b90526136b1565b60006003611a5e6118a7565b611aad57611a6b81612592565b611a875760405162461bcd60e51b81526004016109ea906152be565b611a90816125da565b15611aad5760405162461bcd60e51b81526004016109ea90615527565b610e9389898989898960018a613b47565b6000806000732cf7c0333d9b7f94bbf55b9701227e359f92fd316001600160a01b0316604051611aed90614d58565b600060405180830381855afa9150503d8060008114611b28576040519150601f19603f3d011682016040523d82523d6000602084013e611b2d565b606091505b5091509150818015611b40575080516020145b611b5c5760405162461bcd60e51b81526004016109ea906153ed565b80806020019051810190611b70919061433c565b9250505090565b6000611b816118a7565b611bd057611b8e81612592565b611baa5760405162461bcd60e51b81526004016109ea906152be565b611bb3816125da565b15611bd05760405162461bcd60e51b81526004016109ea90615527565b611bda8585612ef3565b611be5838684613b72565b5050505050565b606081516001600160401b03811115611c1557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611c4e57816020015b611c3b61429e565b815260200190600190039081611c335790505b50905060005b8251811015611dad57600080848381518110611c8057634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316858481518110611cb557634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160601b0316868581518110611cea57634e487b7160e01b600052603260045260246000fd5b602002602001015160400151604051611d039190614cf6565b60006040518083038185875af1925050503d8060008114611d40576040519150601f19603f3d011682016040523d82523d6000602084013e611d45565b606091505b50915091506040518060400160405280831515815260200182815250848481518110611d8157634e487b7160e01b600052603260045260246000fd5b602002602001018190525081611d98575050611dad565b50508080611da59061580d565b915050611c54565b50600081604051602001611dc19190614ea0565b6040516020818303038152906040529050805181602001fd5b6000611de582612592565b92915050565b6000611de5826125da565b6060611e086372b272eb60e01b613c60565b600082516001600160401b03811115611e3157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611e6a57816020015b611e5761429e565b815260200190600190039081611e4f5790505b50915060005b8351811015611fcd57600080858381518110611e9c57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316868481518110611ed157634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160601b0316878581518110611f0657634e487b7160e01b600052603260045260246000fd5b602002602001015160400151604051611f1f9190614cf6565b60006040518083038185875af1925050503d8060008114611f5c576040519150601f19603f3d011682016040523d82523d6000602084013e611f61565b606091505b50915091506040518060400160405280831515815260200182815250858481518110611f9d57634e487b7160e01b600052603260045260246000fd5b602002602001018190525081611fb857600193505050611fcd565b50508080611fc59061580d565b915050611e70565b508015611fe757600082604051602001611dc19190614ea0565b50919050565b6002611ff76118a7565b6120465761200481612592565b6120205760405162461bcd60e51b81526004016109ea906152be565b612029816125da565b156120465760405162461bcd60e51b81526004016109ea90615527565b6003546001600160a01b03168061206f5760405162461bcd60e51b81526004016109ea9061549b565b61208e736b175474e89094c44da98b954eedeac495271d0f8285613b72565b505050565b600060028181610e46565b60006120aa8383612941565b6120b5893389612f87565b610e93338a8a8a8a8a8a8a8a612989565b60026120d06118a7565b61211f576120dd81612592565b6120f95760405162461bcd60e51b81526004016109ea906152be565b612102816125da565b1561211f5760405162461bcd60e51b81526004016109ea90615527565b6004546001600160a01b0316806121485760405162461bcd60e51b81526004016109ea90615619565b61208e73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488285613b72565b60006121716118a7565b61218d5760405162461bcd60e51b81526004016109ea906153a5565b60405163a9059cbb60e01b81526001600160a01b0385169063a9059cbb906121bb9086908690600401614df1565b602060405180830381600087803b1580156121d557600080fd5b505af11580156121e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f57919061494e565b6122156118a7565b6122315760405162461bcd60e51b81526004016109ea906153a5565b61223c816000613cb2565b50565b730efb068354c10c070ddd64a0e8eaf8f054df7e2690565b60006002816006610e46565b60006002816003610e46565b60046122796118a7565b6122c85761228681612592565b6122a25760405162461bcd60e51b81526004016109ea906152be565b6122ab816125da565b156122c85760405162461bcd60e51b81526004016109ea90615527565b6000600260008460068111156122ee57634e487b7160e01b600052602160045260246000fd5b815260208101919091526040016000208054909150600160a01b900460ff161561232a5760405162461bcd60e51b81526004016109ea9061556c565b805460ff60a01b1916600160a01b17815582600681111561235b57634e487b7160e01b600052602160045260246000fd5b6040517fad75709c5a2559beeed6c59693a5ea8701185d51947d3eef38713bb0fe5891e990600090a2505050565b6123916118a7565b6123ad5760405162461bcd60e51b81526004016109ea906153a5565b6001600160a01b0381166123d35760405162461bcd60e51b81526004016109ea90615303565b610f288282613cb2565b6123e56118a7565b6124015760405162461bcd60e51b81526004016109ea906153a5565b6001600160a01b0381166124275760405162461bcd60e51b81526004016109ea90615661565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600060036124556118a7565b6124a45761246281612592565b61247e5760405162461bcd60e51b81526004016109ea906152be565b612487816125da565b156124a45760405162461bcd60e51b81526004016109ea90615527565b600080610b248a8a8b8b8a8a8d612621565b60056124c06118a7565b61250f576124cd81612592565b6124e95760405162461bcd60e51b81526004016109ea906152be565b6124f2816125da565b1561250f5760405162461bcd60e51b81526004016109ea90615527565b61252d7355f2039347564d206ccc6e6ce202853fed386dbf83612f19565b7f70c14fa013d428be746414c53915d6af2495865a3687262ce430049e977d50c58260405161255c91906156be565b60405180910390a15050565b600061258773f1209998bd17eae301a97e3cf7ec17df580e796461291d565b979650505050505050565b6000600260008360068111156125b857634e487b7160e01b600052602160045260246000fd5b81526020810191909152604001600020546001600160a01b0316331492915050565b60006002600083600681111561260057634e487b7160e01b600052602160045260246000fd5b8152602081019190915260400160002054600160a01b900460ff1692915050565b60008080808086600281111561264757634e487b7160e01b600052602160045260246000fd5b141561266c57846126588b8b613d74565b61266291906157ca565b9050849150612679565b6126768a8a613d74565b90505b6126838b8b613d8a565b6000806126a68d73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260006140ad565b915091508a8c141561278257737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03166318cbafe5848c85308e6040518663ffffffff1660e01b81526004016126fa9594939291906156fc565b600060405180830381600087803b15801561271457600080fd5b505af1158015612728573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261275091908101906148bf565b90508060018151811061277357634e487b7160e01b600052603260045260246000fd5b60200260200101519550612811565b6000479050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663791ac947858d86308f6040518663ffffffff1660e01b81526004016127cf9594939291906156fc565b600060405180830381600087803b1580156127e957600080fd5b505af11580156127fd573d6000803e3d6000fd5b50505050804761280d91906157ca565b9650505b600088600281111561283357634e487b7160e01b600052602160045260246000fd5b1461285f5761284c6128458b886157ca565b8890613d74565b935061285884876157ca565b9450612863565b8594505b5050509750975097945050505050565b7f8d4e5e4cf68c4b7be730141ed4b1c725966c0e1df450c1a01b965afa060fa3e08761289f57336128a1565b305b876128ac57856128af565b60005b886128bb5760006128bd565b865b886128f3576001600160a01b03888116146128d857876128ee565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485b6128f6565b60005b87878760405161290c9796959493929190614d89565b60405180910390a150505050505050565b3660008037600080366000845af43d6000803e80801561293c573d6000f35b3d6000fd5b818061296d5750600281600281111561296a57634e487b7160e01b600052602160045260246000fd5b14155b610f285760405162461bcd60e51b81526004016109ea90615253565b6000806000806129998c8b613d8a565b6001600160a01b038b811614156129c5575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486129c8565b50895b85612b55576000806129dc8e8460006140ad565b9092509050737a250d5630b4cf539739df2c5dacb4c659f2488d6338ed17396000896002811115612a1d57634e487b7160e01b600052602160045260246000fd5b14612a28578d612a32565b612a328c8f6157ca565b8d85308e6040518663ffffffff1660e01b8152600401612a569594939291906156fc565b600060405180830381600087803b158015612a7057600080fd5b505af1158015612a84573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612aac91908101906148bf565b905080600181518110612acf57634e487b7160e01b600052603260045260246000fd5b6020026020010151955060016002811115612afa57634e487b7160e01b600052602160045260246000fd5b876002811115612b1a57634e487b7160e01b600052602160045260246000fd5b1415612b4757612b34612b2d8c886157ca565b8b90613d74565b9450612b4085876157ca565b9350612b4e565b8994508593505b5050612e32565b600080612b788e73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260006140ad565b9092509050737a250d5630b4cf539739df2c5dacb4c659f2488d6338ed17396000896002811115612bb957634e487b7160e01b600052602160045260246000fd5b14612bc4578d612bce565b612bce8c8f6157ca565b60028a6002811115612bf057634e487b7160e01b600052602160045260246000fd5b14612bfc576001612bfe565b8c5b85308e6040518663ffffffff1660e01b8152600401612c219594939291906156fc565b600060405180830381600087803b158015612c3b57600080fd5b505af1158015612c4f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c7791908101906148bf565b905080600181518110612c9a57634e487b7160e01b600052603260045260246000fd5b60200260200101519450612cc473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28460006140ad565b9092509050737a250d5630b4cf539739df2c5dacb4c659f2488d6338ed17396002896002811115612d0557634e487b7160e01b600052602160045260246000fd5b14612d105786612d1a565b612d1a8c886157ca565b8d85308e6040518663ffffffff1660e01b8152600401612d3e9594939291906156fc565b600060405180830381600087803b158015612d5857600080fd5b505af1158015612d6c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d9491908101906148bf565b905080600181518110612db757634e487b7160e01b600052603260045260246000fd5b6020026020010151955060016002811115612de257634e487b7160e01b600052602160045260246000fd5b876002811115612e0257634e487b7160e01b600052602160045260246000fd5b1415612e2857612e15612b2d8c886157ca565b9450612e2185876157ca565b9350612e2f565b8994508593505b50505b612eb18d8d8d6002896002811115612e5a57634e487b7160e01b600052602160045260246000fd5b14612e93576001896002811115612e8157634e487b7160e01b600052602160045260246000fd5b14612e8c578f612e8e565b845b612ea9565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b8e8789614263565b6001600160a01b038d163014801590612ed357506001600160a01b038b811614155b15612ee357612ee3818e84613b72565b5050509998505050505050505050565b612efd8282613329565b610f285760405162461bcd60e51b81526004016109ea906150d2565b6000826001600160a01b031682604051612f3290614d58565b60006040518083038185875af1925050503d8060008114612f6f576040519150601f19603f3d011682016040523d82523d6000602084013e612f74565b606091505b505090508061208e573d6000803e3d6000fd5b600080846001600160a01b03166323b872dd60e01b853086604051602401612fb193929190614dcd565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612fef9190614cf6565b6000604051808303816000865af19150503d806000811461302c576040519150601f19603f3d011682016040523d82523d6000602084013e613031565b606091505b509150915081801561305b57508051158061305b57508080602001905181019061305b919061494e565b611be55760405162461bcd60e51b81526004016109ea9061515f565b6040805160028082526060820183526000928392839283928392919060208301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816000815181106130d857634e487b7160e01b600052603260045260246000fd5b6001600160a01b0392831660209182029290920101528c811614156131555773a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160018151811061312d57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b0316815250503091506131a7565b8b8160018151811061317757634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b031681525050876131a257336131a4565b305b91505b604080516002808252606082018352600092602083019080368337019050509050737a250d5630b4cf539739df2c5dacb4c659f2488d637ff36ab560018a600281111561320457634e487b7160e01b600052602160045260246000fd5b1415613210578d61321a565b61321a898f6157ca565b8d85878f6040518663ffffffff1660e01b815260040161323d94939291906156c7565b6000604051808303818588803b15801561325657600080fd5b505af115801561326a573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261329391908101906148bf565b9050806001815181106132b657634e487b7160e01b600052603260045260246000fd5b60200260200101519550600160028111156132e157634e487b7160e01b600052602160045260246000fd5b88600281111561330157634e487b7160e01b600052602160045260246000fd5b14156133145761284c6128458c886157ca565b50939b8c9b5094995093975050505050505050565b600080604051806104c001604052806104928152602001615878610492913960405161335d91908590600090602001614d12565b60408051601f19818403018152919052805160209091012090506000805b600a81101561341a576040516133b9907ffffc00c80b0000007f73004edb00094cad80626d8d00000000000000000000009083908690602001614cc0565b6040516020818303038152906040528051906020012060001c9150856001600160a01b0316826001600160a01b031614156133fa5760019350505050611de5565b806134048161580d565b91505080806134129061580d565b91505061337b565b50600095945050505050565b60606044825111801561346c57508151600160fb1b90839060009061345b57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916145b80156134ad5750815160c360f81b908390600190811061349c57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916145b80156134ee57508151607960f81b90839060029081106134dd57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916145b801561352f57508151600560fd1b908390600390811061351e57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916145b156136415760006004835161354491906157ca565b6001600160401b0381111561356957634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613593576020820181803683370190505b50905060045b8351811015613624578381815181106135c257634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916826135dd6004846157ca565b815181106135fb57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053508061361c8161580d565b915050613599565b50808060200190518101906136399190614b2e565b91505061366c565b50604080518082019091526012815271286e6f2072657665727420726561736f6e2960701b60208201525b919050565b600281600281111561369357634e487b7160e01b600052602160045260246000fd5b141561223c5760405162461bcd60e51b81526004016109ea906151f6565b6000806001600160a01b03801683604001516001600160a01b0316146136db5782604001516136f1565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485b905061370583602001518460800151613d8a565b600061371b8460200151838661012001516140ad565b5090506000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161374c9190614d5b565b60206040518083038186803b15801561376457600080fd5b505afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c9190614b8b565b9050737a250d5630b4cf539739df2c5dacb4c659f2488d635c11d795600087610140015160028111156137df57634e487b7160e01b600052602160045260246000fd5b146137ee578660800151613802565b8660e00151876080015161380291906157ca565b8760a0015185308a61010001516040518663ffffffff1660e01b815260040161382f9594939291906156fc565b600060405180830381600087803b15801561384957600080fd5b505af115801561385d573d6000803e3d6000fd5b50506040516370a0823160e01b81528392506001600160a01b03861691506370a082319061388f903090600401614d5b565b60206040518083038186803b1580156138a757600080fd5b505afa1580156138bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138df9190614b8b565b6138e991906157ca565b8551909450600092506001600160a01b0316301480159150613919575060408401516001600160a01b0390811614155b15613aa25783516040516370a0823160e01b81526000916001600160a01b038516916370a082319161394d91600401614d5b565b60206040518083038186803b15801561396557600080fd5b505afa158015613979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061399d9190614b8b565b85519091506139ee908490600188610140015160028111156139cf57634e487b7160e01b600052602160045260246000fd5b146139da57866139e9565b60e08801516139e990886157ca565b613b72565b84516040516370a0823160e01b815282916001600160a01b038616916370a0823191613a1c91600401614d5b565b60206040518083038186803b158015613a3457600080fd5b505afa158015613a48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a6c9190614b8b565b613a7691906157ca565b9150508360c00151811015613a9d5760405162461bcd60e51b81526004016109ea906155af565b613ae6565b60018461014001516002811115613ac957634e487b7160e01b600052602160045260246000fd5b14613ad45782613ae3565b60e0840151613ae390846157ca565b90505b835160208501516040860151613b4092919060018861014001516002811115613b1f57634e487b7160e01b600052602160045260246000fd5b14613b2e578760200151613b30565b855b8860600151868a60e00151614263565b5050919050565b6000613b6673f1209998bd17eae301a97e3cf7ec17df580e796461291d565b98975050505050505050565b600080846001600160a01b031663a9059cbb60e01b8585604051602401613b9a929190614df1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613bd89190614cf6565b6000604051808303816000865af19150503d8060008114613c15576040519150601f19603f3d011682016040523d82523d6000602084013e613c1a565b606091505b5091509150818015613c44575080511580613c44575080806020019051810190613c44919061494e565b611be55760405162461bcd60e51b81526004016109ea90615424565b3330148015613c8557506007546001600160e01b031982811661010090920460e01b16145b613ca15760405162461bcd60e51b81526004016109ea9061518c565b506007805464ffffffff0019169055565b600060026000846006811115613cd857634e487b7160e01b600052602160045260246000fd5b8152602081019190915260400160002080549091506001600160a01b0383811691161461208e5780546001600160a01b0319166001600160a01b038316178155826006811115613d3857634e487b7160e01b600052602160045260246000fd5b7f40ab465936efb8324cf37e3a29170c60d9b81de43af89693ce9d92c761e42adc83604051613d679190614d5b565b60405180910390a2505050565b6000818310613d835781610f6b565b5090919050565b604051636eb1769f60e11b815281906001600160a01b0384169063dd62ed3e90613dce903090737a250d5630b4cf539739df2c5dacb4c659f2488d90600401614d6f565b60206040518083038186803b158015613de657600080fd5b505afa158015613dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e1e9190614b8b565b1015610f2857600080836001600160a01b031663095ea7b360e01b737a250d5630b4cf539739df2c5dacb4c659f2488d6000604051602401613e61929190614df1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613e9f9190614cf6565b6000604051808303816000865af19150503d8060008114613edc576040519150601f19603f3d011682016040523d82523d6000602084013e613ee1565b606091505b5091509150836001600160a01b031663095ea7b360e01b737a250d5630b4cf539739df2c5dacb4c659f2488d600019604051602401613f21929190614df1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613f5f9190614cf6565b6000604051808303816000865af19150503d8060008114613f9c576040519150601f19603f3d011682016040523d82523d6000602084013e613fa1565b606091505b5090925090508161406c57836001600160a01b031663095ea7b360e01b737a250d5630b4cf539739df2c5dacb4c659f2488d85604051602401613fe5929190614df1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516140239190614cf6565b6000604051808303816000865af19150503d8060008114614060576040519150601f19603f3d011682016040523d82523d6000602084013e614065565b606091505b5090925090505b818015614091575080511580614091575080806020019051810190614091919061494e565b610cdf5760405162461bcd60e51b81526004016109ea90615452565b6060806000836140be5760026140c1565b60035b60ff1690506000816001600160401b038111156140ee57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015614117578160200160208202803683370190505b509050868160008151811061413c57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505084156141b95773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061419857634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b0316815250505b85816141c66001856157ca565b815181106141e457634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505080826001600160401b0381111561422b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015614254578160200160208202803683370190505b50935093505050935093915050565b7f8d4e5e4cf68c4b7be730141ed4b1c725966c0e1df450c1a01b965afa060fa3e08787878787878760405161290c9796959493929190614d89565b60408051808201909152600081526060602082015290565b60006142c96142c48461578b565b615738565b90508281528383830111156142dd57600080fd5b610f6b8360208301846157e1565b80356003811061366c57600080fd5b80356007811061366c57600080fd5b80356001600160601b038116811461366c57600080fd5b600060208284031215614331578081fd5b8135610f6b81615854565b60006020828403121561434d578081fd5b8151610f6b81615854565b60008060006060848603121561436c578182fd5b833561437781615854565b9250602084013561438781615854565b929592945050506040919091013590565b600080604083850312156143aa578182fd5b82356143b581615854565b946020939093013593505050565b600080600080606085870312156143d8578182fd5b84356143e381615854565b93506020850135925060408501356001600160401b0380821115614405578384fd5b818701915087601f830112614418578384fd5b813581811115614426578485fd5b886020828501011115614437578485fd5b95989497505060200194505050565b60008060408385031215614458578182fd5b823561446381615854565b9150602083013561447381615854565b809150509250929050565b60008060008060808587031215614493578182fd5b843561449e81615854565b935060208501356144ae81615854565b925060408501356144be81615854565b9396929550929360600135925050565b600080600080608085870312156144e3578182fd5b84356144ee81615854565b966020860135965060408601359560600135945092505050565b600080600080600060a0868803121561451f578283fd5b853561452a81615854565b945060208601359350604086013592506060860135915061454d608087016142eb565b90509295509295909350565b600080600080600060a08688031215614570578283fd5b853561457b81615854565b97602087013597506040870135966060810135965060800135945092505050565b60008060008060008060c087890312156145b4578384fd5b86356145bf81615854565b9550602087013594506040870135935060608701359250608087013591506145e960a088016142eb565b90509295509295509295565b600080600080600080600060e0888a03121561460f578485fd5b873561461a81615854565b96506020880135955060408801359450606088013593506080880135925060a0880135915061464b60c089016142eb565b905092959891949750929550565b6000602080838503121561466b578182fd5b82516001600160401b0380821115614681578384fd5b818501915085601f830112614694578384fd5b81516146a26142c482615768565b81815284810190848601875b848110156147325781518701604080601f19838f030112156146ce578a8bfd5b6146d781615738565b8a8301516146e481615869565b815282820151898111156146f6578c8dfd5b8084019350508d603f84011261470a578b8cfd5b61471a8e8c8501518486016142b6565b818c01528652505092870192908701906001016146ae565b50909998505050505050505050565b60008060208385031215614753578182fd5b82356001600160401b0380821115614769578384fd5b818501915085601f83011261477c578384fd5b81358181111561478a578485fd5b866020808302850101111561479d578485fd5b60209290920196919550909350505050565b600060208083850312156147c1578182fd5b82356001600160401b03808211156147d7578384fd5b818501915085601f8301126147ea578384fd5b81356147f86142c482615768565b81815284810190848601875b848110156147325781358701606080601f19838f03011215614824578a8bfd5b61482d81615738565b8a83013561483a81615854565b81526040614849848201614309565b828d015291830135918983111561485e578c8dfd5b82840193508e603f850112614871578c8dfd5b8b84013592506148836142c48461578b565b8381528f82858701011115614896578d8efd5b838286018e8301379283018c018d90528101919091528552509287019290870190600101614804565b600060208083850312156148d1578182fd5b82516001600160401b038111156148e6578283fd5b8301601f810185136148f6578283fd5b80516149046142c482615768565b8181528381019083850185840285018601891015614920578687fd5b8694505b83851015614942578051835260019490940193918501918501614924565b50979650505050505050565b60006020828403121561495f578081fd5b8151610f6b81615869565b60008060006060848603121561436c578081fd5b600080600080600080600060e0888a031215614998578081fd5b87356149a381615854565b965060208801356149b381615854565b955060408801359450606088013593506080880135925060a0880135915060c08801356149df81615869565b8091505092959891949750929550565b600080600080600080600080610100898b031215614a0b578182fd5b8835614a1681615854565b97506020890135614a2681615854565b965060408901359550606089013594506080890135935060a0890135925060c0890135614a5281615869565b9150614a6060e08a016142eb565b90509295985092959890939650565b60008060008060008060008060006101208a8c031215614a8d578283fd5b8935614a9881615854565b985060208a0135614aa881615854565b975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135614adb81615869565b9150614aea6101008b016142eb565b90509295985092959850929598565b600060208284031215614b0a578081fd5b610f6b826142fa565b60008060408385031215614b25578182fd5b614463836142fa565b600060208284031215614b3f578081fd5b81516001600160401b03811115614b54578182fd5b8201601f81018413614b64578182fd5b610f57848251602084016142b6565b600060208284031215614b84578081fd5b5035919050565b600060208284031215614b9c578081fd5b5051919050565b6000815180845260208085019450808401835b83811015614bdb5781516001600160a01b031687529582019590820190600101614bb6565b509495945050505050565b6000815180845260208085019450808401835b83811015614bdb578151151587529582019590820190600101614bf9565b6000815180845260208085018081965082840281019150828601855b85811015614c5d578284038952614c4b848351614c94565b98850198935090840190600101614c33565b5091979650505050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452614cac8160208601602086016157e1565b601f01601f19169290920160200192915050565b6affffffffffffffffffffff199390931683526015830191909152603582015260550190565b6000828483379101908152919050565b60008251614d088184602087016157e1565b9190910192915050565b60008451614d248184602089016157e1565b60609490941b6bffffffffffffffffffffffff19169190930190815263ffffffff1991909116601482015260300192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03978816815295871660208701529386166040860152919094166060840152608083019390935260a082019290925260c081019190915260e00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260806040830152614e316080830185614c94565b82810360608401526125878185614c94565b600060408252614e566040830185614be6565b828103602084015261188f8185614c17565b600060608252614e7b6060830186614be6565b8281036020840152614e8d8186614c17565b9150508215156040830152949350505050565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614f0557888303603f190185528151805115158452870151878401879052614ef287850182614c94565b9588019593505090860190600101614ec4565b509098975050505050505050565b602080825281810183905260009060408084018583028501820187855b88811015614f0557878303603f190184528135368b9003605e19018112614f55578788fd5b8a0160608135614f6481615854565b6001600160a01b031685526001600160601b03614f82838a01614309565b168886015286820135601e19833603018112614f9c57898afd5b820180356001600160401b03811115614fb3578a8bfd5b803603841315614fc1578a8bfd5b8289880152614fd5838801828c8501614c6a565b978a019796505050928701925050600101614f30565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614f0557888303603f19018552815180516001600160a01b03168452878101516001600160601b031688850152860151606087850181905261505781860183614c94565b96890196945050509086019060010161500f565b901515815260200190565b6000861515825260018060a01b038616602083015284604083015260a060608301526150a560a0830185614c94565b8281036080840152613b668185614c94565b6000831515825260406020830152610f576040830184614c94565b6020808252603a908201527f436f756c64206e6f74207265736f6c766520736d6172742077616c6c6574207560408201527f73696e672070726f7669646564207369676e696e67206b65792e000000000000606082015260800190565b602080825260169082015275496e76616c69642063616c6c2064657465637465642160501b604082015260600190565b6020808252601390820152722a3930b739b332b91034b7103330b4b632b21760691b604082015260600190565b60208082526044908201527f45787465726e616c206163636f756e7473206f7220756e617070726f7665642060408201527f696e7465726e616c2066756e6374696f6e732063616e6e6f742063616c6c20746060820152633434b99760e11b608082015260a00190565b6020808252603e908201527f43616e6e6f742074616b6520746f6b656e2d666f722d746f6b656e206665652060408201527f696e204574686572207769746820666565206f6e207472616e736665722e0000606082015260800190565b60208082526045908201527f43616e6e6f742074616b6520746f6b656e2d666f722d746f6b656e206665652060408201527f696e20457468657220756e6c65737320726f75746564207468726f75676820456060820152643a3432b91760d91b608082015260a00190565b60208082526025908201527f43616c6c657220646f6573206e6f7420686176652061207265717569726564206040820152643937b6329760d91b606082015260800190565b60208082526017908201527f4d75737420737570706c7920616e206163636f756e742e000000000000000000604082015260600190565b60208082526045908201527f54776f537465704f776e61626c653a2063757272656e74206f776e6572206d7560408201527f7374207365742063616c6c6572206173206e657720706f74656e7469616c206f6060820152643bb732b91760d91b608082015260a00190565b60208082526028908201527f54776f537465704f776e61626c653a2063616c6c6572206973206e6f74207468604082015267329037bbb732b91760c11b606082015260800190565b60208082526017908201527f496e76616c696420696d706c656d656e746174696f6e2e000000000000000000604082015260600190565b6020808252601490820152732a3930b739b332b91037baba103330b4b632b21760611b604082015260600190565b60208082526029908201527f546f6b656e20617070726f76616c20666f7220556e697377617020726f75746560408201526839103330b4b632b21760b91b606082015260800190565b60208082526027908201527f4e6f20446169207072696d61727920726563697069656e742063757272656e74604082015266363c9039b2ba1760c91b606082015260800190565b60208082526025908201527f526f6c6520696e207175657374696f6e20697320616c726561647920756e70616040820152643ab9b2b21760d91b606082015260800190565b60208082526025908201527f526f6c6520696e207175657374696f6e2069732063757272656e746c792070616040820152643ab9b2b21760d91b606082015260800190565b60208082526023908201527f526f6c6520696e207175657374696f6e20697320616c7265616479207061757360408201526232b21760e91b606082015260800190565b60208082526044908201527f526563656976656420746f6b656e20616d6f756e74206166746572207472616e60408201527f7366657220666565206973206c657373207468616e2071756f74656420616d6f6060820152633ab73a1760e11b608082015260a00190565b60208082526028908201527f4e6f2055534443207072696d61727920726563697069656e742063757272656e6040820152673a363c9039b2ba1760c11b606082015260800190565b60208082526038908201527f54776f537465704f776e61626c653a206e657720706f74656e7469616c206f7760408201527f6e657220697320746865207a65726f20616464726573732e0000000000000000606082015260800190565b90815260200190565b6000858252608060208301526156e06080830186614ba3565b6001600160a01b03949094166040830152506060015292915050565b600086825285602083015260a0604083015261571b60a0830186614ba3565b6001600160a01b0394909416606083015250608001529392505050565b604051601f8201601f191681016001600160401b03811182821017156157605761576061583e565b604052919050565b60006001600160401b038211156157815761578161583e565b5060209081020190565b60006001600160401b038211156157a4576157a461583e565b50601f01601f191660200190565b600082198211156157c5576157c5615828565b500190565b6000828210156157dc576157dc615828565b500390565b60005b838110156157fc5781810151838201526020016157e4565b83811115610cdf5750506000910152565b600060001982141561582157615821615828565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461223c57600080fd5b801515811461223c57600080fdfe60806040526040516104423803806104428339818101604052602081101561002657600080fd5b810190808051604051939291908464010000000082111561004657600080fd5b90830190602082018581111561005b57600080fd5b825164010000000081118282018810171561007557600080fd5b82525081516020918201929091019080838360005b838110156100a257818101518382015260200161008a565b50505050905090810190601f1680156100cf5780820380516001836020036101000a031916815260200191505b5060405250505060006100e661019e60201b60201c565b6001600160a01b0316826040518082805190602001908083835b6020831061011f5780518252601f199092019160209182019101610100565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461017f576040519150601f19603f3d011682016040523d82523d6000602084013e610184565b606091505b5050905080610197573d6000803e3d6000fd5b50506102be565b60405160009081906060906e26750c571ce882b17016557279adaa9083818181855afa9150503d80600081146101f0576040519150601f19603f3d011682016040523d82523d6000602084013e6101f5565b606091505b509150915081819061029f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026457818101518382015260200161024c565b50505050905090810190601f1680156102915780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508080602001905160208110156102b557600080fd5b50519392505050565b610175806102cd6000396000f3fe608060405261001461000f610016565b61011c565b005b60405160009081906060906e26750c571ce882b17016557279adaa9083818181855afa9150503d8060008114610068576040519150601f19603f3d011682016040523d82523d6000602084013e61006d565b606091505b50915091508181906100fd5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156100c25781810151838201526020016100aa565b50505050905090810190601f1680156100ef5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5080806020019051602081101561011357600080fd5b50519392505050565b3660008037600080366000845af43d6000803e80801561013b573d6000f35b3d6000fdfea265627a7a7231582020202020202055706772616465426561636f6e50726f7879563120202020202064736f6c634300050b003200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000024c4d66de8000000000000000000000000a2646970667358221220784b1cc3f6622b5c7aae2f03aa8870aed35115d5feb5040157029b0dff2d8f2364736f6c63430008010033000000000000000000000000c982ee89bc9395c8bb470f9816bee3a257bb1e9b
Deployed Bytecode
0x6080604052600436106103385760003560e01c80638f32d59b116101ab578063c6102aa8116100f7578063eb68b08a11610095578063f2fde38b1161006f578063f2fde38b14610946578063f495018714610966578063f816c0fa14610986578063f97086f6146109a657610378565b8063eb68b08a146108f1578063edf07f1514610906578063f2e12a391461092657610378565b8063d9caed12116100d1578063d9caed1214610887578063dab41d0d146108a7578063de7b5d14146108c7578063e20ed9d2146108dc57610378565b8063c6102aa814610832578063c90418b414610847578063cef0a6041461086757610378565b8063afd6116b11610164578063bb6033201161013e578063bb603320146107b2578063bc61e733146107d2578063c21e4e42146107f2578063c54d559e1461081257610378565b8063afd6116b1461075c578063b1f2aa6714610789578063badafb37146107a457610378565b80638f32d59b146106b25780639b86f0ef146106c7578063a0a6d75f146106e7578063a735559614610707578063aaf10f4214610727578063aeed28611461073c57610378565b8063329504da116102855780637008b5481161022357806378a967aa116101fd57806378a967aa1461064857806379ba5097146106685780638218a8e91461067d5780638da5cb5b1461069d57610378565b80637008b548146105d657806372b272eb146105eb5780637787c5871461061957610378565b8063522f68151161025f578063522f6815146105545780635ce4a04914610574578063618fdbb0146105895780636b309696146105a957610378565b8063329504da1461050c5780633efa667e146105215780634d0757eb1461054157610378565b806321a012ec116102f2578063301c7e5d116102cc578063301c7e5d146104a25780633059d1d3146104c257806331ab6d2a146104d757806331ae1f02146104f757610378565b806321a012ec1461044d57806323452b9c1461046d5780632e5cd5f31461048257610378565b806263f2fb1461037d5780630d8e6e2c1461039f57806312e6bf6a146103ca57806312fd415a146103f8578063153f92eb1461041857806318b93e461461043a57610378565b36610378577f1e57e3bb474320be3d2c77138f75b7c3941292d647f5f9634e33a8e94e0e069b333460405161036e929190614df1565b60405180910390a1005b600080fd5b34801561038957600080fd5b5061039d610398366004614320565b6109c6565b005b3480156103ab57600080fd5b506103b4610a15565b6040516103c191906156be565b60405180910390f35b3480156103d657600080fd5b506103ea6103e53660046143c3565b610a1a565b6040516103c19291906150b7565b34801561040457600080fd5b506103b461041336600461459c565b610aad565b34801561042457600080fd5b5061042d610b6b565b6040516103c19190614d5b565b6103b461044836600461459c565b610b8f565b34801561045957600080fd5b506103b46104683660046149ef565b610bb8565b34801561047957600080fd5b5061039d610c3c565b34801561048e57600080fd5b5061039d61049d366004614358565b610c72565b3480156104ae57600080fd5b5061039d6104bd366004614af9565b610ce5565b3480156104ce57600080fd5b5061042d610dc2565b3480156104e357600080fd5b506103b46104f236600461459c565b610dd1565b34801561050357600080fd5b5061042d610e3f565b34801561051857600080fd5b5061042d610e65565b34801561052d57600080fd5b506103b461053c366004614a6f565b610e74565b6103b461054f366004614508565b610ea0565b34801561056057600080fd5b5061039d61056f366004614398565b610efa565b34801561058057600080fd5b5061042d610f2c565b34801561059557600080fd5b506103b46105a43660046144ce565b610f38565b3480156105b557600080fd5b506105c96105c4366004614446565b610f5f565b6040516103c1919061506b565b3480156105e257600080fd5b5061042d610f72565b3480156105f757600080fd5b5061060b6106063660046147af565b610f7e565b6040516103c1929190614e43565b34801561062557600080fd5b50610639610634366004614741565b61147c565b6040516103c193929190614e68565b34801561065457600080fd5b5061039d610663366004614320565b6117a4565b34801561067457600080fd5b5061039d6117ea565b34801561068957600080fd5b506103b4610698366004614559565b611870565b3480156106a957600080fd5b5061042d611898565b3480156106be57600080fd5b506105c96118a7565b3480156106d357600080fd5b506103b46106e236600461459c565b6118b8565b3480156106f357600080fd5b506103b46107023660046149ef565b61195f565b34801561071357600080fd5b506103b46107223660046145f5565b611a52565b34801561073357600080fd5b5061042d611abe565b34801561074857600080fd5b5061039d61075736600461447e565b611b77565b34801561076857600080fd5b5061077c6107773660046147af565b611bec565b6040516103c19190614ea0565b34801561079557600080fd5b506103b461044836600461459c565b6103b46105a43660046144ce565b3480156107be57600080fd5b506105c96107cd366004614af9565b611dda565b3480156107de57600080fd5b506105c96107ed366004614af9565b611deb565b3480156107fe57600080fd5b5061077c61080d3660046147af565b611df6565b34801561081e57600080fd5b5061039d61082d366004614b73565b611fed565b34801561083e57600080fd5b5061042d612093565b34801561085357600080fd5b506103b46108623660046149ef565b61209e565b34801561087357600080fd5b5061039d610882366004614b73565b6120c6565b34801561089357600080fd5b506105c96108a236600461496a565b612167565b3480156108b357600080fd5b5061039d6108c2366004614af9565b61220d565b3480156108d357600080fd5b5061042d61223f565b3480156108e857600080fd5b5061042d612257565b3480156108fd57600080fd5b5061042d612263565b34801561091257600080fd5b5061039d610921366004614af9565b61226f565b34801561093257600080fd5b5061039d610941366004614b13565b612389565b34801561095257600080fd5b5061039d610961366004614320565b6123dd565b34801561097257600080fd5b506103b461098136600461459c565b612449565b34801561099257600080fd5b5061039d6109a1366004614b73565b6124b6565b3480156109b257600080fd5b506103b46109c136600461497e565b612568565b6109ce6118a7565b6109f35760405162461bcd60e51b81526004016109ea906153a5565b60405180910390fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b601390565b60006060610a266118a7565b610a425760405162461bcd60e51b81526004016109ea906153a5565b856001600160a01b0316858585604051610a5d929190614ce6565b60006040518083038185875af1925050503d8060008114610a9a576040519150601f19603f3d011682016040523d82523d6000602084013e610a9f565b606091505b509097909650945050505050565b60006003610ab96118a7565b610b0857610ac681612592565b610ae25760405162461bcd60e51b81526004016109ea906152be565b610aeb816125da565b15610b085760405162461bcd60e51b81526004016109ea90615527565b600080610b248a610b1a8b60016157b2565b8b8b8a8a8d612621565b91955092509050610b5e6001600080886002811115610b5357634e487b7160e01b600052602160045260246000fd5b14158d8d8787612873565b5050509695505050505050565b7f000000000000000000000000c982ee89bc9395c8bb470f9816bee3a257bb1e9b81565b6000610bae73f1209998bd17eae301a97e3cf7ec17df580e796461291d565b9695505050505050565b60006003610bc46118a7565b610c1357610bd181612592565b610bed5760405162461bcd60e51b81526004016109ea906152be565b610bf6816125da565b15610c135760405162461bcd60e51b81526004016109ea90615527565b610c1d8484612941565b610c2e308b8b8b8b8b8b8b8b612989565b9a9950505050505050505050565b610c446118a7565b610c605760405162461bcd60e51b81526004016109ea906153a5565b600180546001600160a01b0319169055565b6000610c7c6118a7565b610ccb57610c8981612592565b610ca55760405162461bcd60e51b81526004016109ea906152be565b610cae816125da565b15610ccb5760405162461bcd60e51b81526004016109ea90615527565b610cd58484612ef3565b610cdf8483612f19565b50505050565b610ced6118a7565b610d095760405162461bcd60e51b81526004016109ea906153a5565b600060026000836006811115610d2f57634e487b7160e01b600052602160045260246000fd5b815260208101919091526040016000208054909150600160a01b900460ff16610d6a5760405162461bcd60e51b81526004016109ea906154e2565b805460ff60a01b19168155816006811115610d9557634e487b7160e01b600052602160045260246000fd5b6040517fd9ff16dcccc040d408ddf47191ae2d5313510993b245b3a7ccfb0258a4401d7890600090a25050565b6004546001600160a01b031690565b6000610dde873388612f87565b600080610df089898a8a89898c612621565b91945092509050610e2960008080876002811115610e1e57634e487b7160e01b600052602160045260246000fd5b14158c8c8787612873565b610e333383612f19565b50509695505050505050565b6000600281805b81526020810191909152604001600020546001600160a01b0316919050565b6003546001600160a01b031690565b6000610e9373f1209998bd17eae301a97e3cf7ec17df580e796461291d565b9998505050505050505050565b6000806000610eb5883489886000898c613077565b91945092509050610eef6000600180876002811115610ee457634e487b7160e01b600052602160045260246000fd5b14158b348787612873565b505095945050505050565b610f026118a7565b610f1e5760405162461bcd60e51b81526004016109ea906153a5565b610f288282612f19565b5050565b60006002816005610e46565b6000610f5773f1209998bd17eae301a97e3cf7ec17df580e796461291d565b949350505050565b6000610f6b8383613329565b9392505050565b60006002816004610e46565b6060806006610f8b6118a7565b610fda57610f9881612592565b610fb45760405162461bcd60e51b81526004016109ea906152be565b610fbd816125da565b15610fda5760405162461bcd60e51b81526004016109ea90615527565b60405163c7cbc79960e01b81526000906001600160a01b037f000000000000000000000000c982ee89bc9395c8bb470f9816bee3a257bb1e9b169063c7cbc79990611029908890600401614feb565b60206040518083038186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611079919061494e565b9050806110985760405162461bcd60e51b81526004016109ea9061512f565b84516001600160401b038111156110bf57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156110e8578160200160208202803683370190505b50935084516001600160401b0381111561111257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561114557816020015b60608152602001906001900390816111305790505b506007805464ffffffff0019166472b272eb001790556040519093506000908190309063610f272160e11b9061117f908a90602401614feb565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516111bd9190614cf6565b6000604051808303816000865af19150503d80600081146111fa576040519150601f19603f3d011682016040523d82523d6000602084013e6111ff565b606091505b509150915081611218576007805464ffffffff00191690555b60008180602001905181019061122e9190614659565b905060005b815181101561147157600089828151811061125e57634e487b7160e01b600052603260045260246000fd5b6020026020010151905082828151811061128857634e487b7160e01b600052603260045260246000fd5b6020026020010151600001518983815181106112b457634e487b7160e01b600052603260045260246000fd5b6020026020010190151590811515815250508282815181106112e657634e487b7160e01b600052603260045260246000fd5b60200260200101516020015188838151811061131257634e487b7160e01b600052603260045260246000fd5b602002602001018190525082828151811061133d57634e487b7160e01b600052603260045260246000fd5b602002602001015160000151156113d3577f26f13c2c104b2a1b3f0b1c6232d84f2bba70d231216636c3ceeebea631eb97dd8515826000015183602001516001600160601b031684604001518787815181106113a957634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516040516113c6959493929190615076565b60405180910390a161145e565b7f2007dedc5d6ba6b20b13bb9cbff9121300b36978bbac6fbbc5ccadaa1ff6c668816000015182602001516001600160601b0316836040015161144087878151811061142f57634e487b7160e01b600052603260045260246000fd5b602002602001015160200151613426565b6040516114509493929190614e0a565b60405180910390a150611471565b50806114698161580d565b915050611233565b505050505050915091565b60608060007f000000000000000000000000c982ee89bc9395c8bb470f9816bee3a257bb1e9b6001600160a01b031663c7cbc79986866040518363ffffffff1660e01b81526004016114cf929190614f13565b60206040518083038186803b1580156114e757600080fd5b505afa1580156114fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151f919061494e565b9050836001600160401b0381111561154757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611570578160200160208202803683370190505b509250836001600160401b0381111561159957634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156115cc57816020015b60608152602001906001900390816115b75790505b5091506000306001600160a01b031663afd6116b60e01b87876040516024016115f6929190614f13565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516116349190614cf6565b6000604051808303816000865af19150503d8060008114611671576040519150601f19603f3d011682016040523d82523d6000602084013e611676565b606091505b509150506000818060200190518101906116909190614659565b905060005b815181101561179a578181815181106116be57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001518682815181106116ea57634e487b7160e01b600052603260045260246000fd5b60200260200101901515908115158152505081818151811061171c57634e487b7160e01b600052603260045260246000fd5b60200260200101516020015185828151811061174857634e487b7160e01b600052603260045260246000fd5b602002602001018190525081818151811061177357634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516117885761179a565b806117928161580d565b915050611695565b5050509250925092565b6117ac6118a7565b6117c85760405162461bcd60e51b81526004016109ea906153a5565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146118145760405162461bcd60e51b81526004016109ea9061533a565b600180546001600160a01b03191690556000805460405133926001600160a01b03909216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b03191633179055565b600061188f73f1209998bd17eae301a97e3cf7ec17df580e796461291d565b95945050505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b600060036118c46118a7565b611913576118d181612592565b6118ed5760405162461bcd60e51b81526004016109ea906152be565b6118f6816125da565b156119135760405162461bcd60e51b81526004016109ea90615527565b6000806119268a8a8a8960018a8d613077565b91955092509050610b5e6001808088600281111561195457634e487b7160e01b600052602160045260246000fd5b14158d8d878d612873565b6000600361196b6118a7565b6119ba5761197881612592565b6119945760405162461bcd60e51b81526004016109ea906152be565b61199d816125da565b156119ba5760405162461bcd60e51b81526004016109ea90615527565b6119c383613671565b610c2e604051806101600160405280306001600160a01b031681526020018c6001600160a01b031681526020018b6001600160a01b031681526020018a81526020018a81526020018981526020018a81526020018881526020018781526020018615158152602001856002811115611a4b57634e487b7160e01b600052602160045260246000fd5b90526136b1565b60006003611a5e6118a7565b611aad57611a6b81612592565b611a875760405162461bcd60e51b81526004016109ea906152be565b611a90816125da565b15611aad5760405162461bcd60e51b81526004016109ea90615527565b610e9389898989898960018a613b47565b6000806000732cf7c0333d9b7f94bbf55b9701227e359f92fd316001600160a01b0316604051611aed90614d58565b600060405180830381855afa9150503d8060008114611b28576040519150601f19603f3d011682016040523d82523d6000602084013e611b2d565b606091505b5091509150818015611b40575080516020145b611b5c5760405162461bcd60e51b81526004016109ea906153ed565b80806020019051810190611b70919061433c565b9250505090565b6000611b816118a7565b611bd057611b8e81612592565b611baa5760405162461bcd60e51b81526004016109ea906152be565b611bb3816125da565b15611bd05760405162461bcd60e51b81526004016109ea90615527565b611bda8585612ef3565b611be5838684613b72565b5050505050565b606081516001600160401b03811115611c1557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611c4e57816020015b611c3b61429e565b815260200190600190039081611c335790505b50905060005b8251811015611dad57600080848381518110611c8057634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316858481518110611cb557634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160601b0316868581518110611cea57634e487b7160e01b600052603260045260246000fd5b602002602001015160400151604051611d039190614cf6565b60006040518083038185875af1925050503d8060008114611d40576040519150601f19603f3d011682016040523d82523d6000602084013e611d45565b606091505b50915091506040518060400160405280831515815260200182815250848481518110611d8157634e487b7160e01b600052603260045260246000fd5b602002602001018190525081611d98575050611dad565b50508080611da59061580d565b915050611c54565b50600081604051602001611dc19190614ea0565b6040516020818303038152906040529050805181602001fd5b6000611de582612592565b92915050565b6000611de5826125da565b6060611e086372b272eb60e01b613c60565b600082516001600160401b03811115611e3157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611e6a57816020015b611e5761429e565b815260200190600190039081611e4f5790505b50915060005b8351811015611fcd57600080858381518110611e9c57634e487b7160e01b600052603260045260246000fd5b6020026020010151600001516001600160a01b0316868481518110611ed157634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160601b0316878581518110611f0657634e487b7160e01b600052603260045260246000fd5b602002602001015160400151604051611f1f9190614cf6565b60006040518083038185875af1925050503d8060008114611f5c576040519150601f19603f3d011682016040523d82523d6000602084013e611f61565b606091505b50915091506040518060400160405280831515815260200182815250858481518110611f9d57634e487b7160e01b600052603260045260246000fd5b602002602001018190525081611fb857600193505050611fcd565b50508080611fc59061580d565b915050611e70565b508015611fe757600082604051602001611dc19190614ea0565b50919050565b6002611ff76118a7565b6120465761200481612592565b6120205760405162461bcd60e51b81526004016109ea906152be565b612029816125da565b156120465760405162461bcd60e51b81526004016109ea90615527565b6003546001600160a01b03168061206f5760405162461bcd60e51b81526004016109ea9061549b565b61208e736b175474e89094c44da98b954eedeac495271d0f8285613b72565b505050565b600060028181610e46565b60006120aa8383612941565b6120b5893389612f87565b610e93338a8a8a8a8a8a8a8a612989565b60026120d06118a7565b61211f576120dd81612592565b6120f95760405162461bcd60e51b81526004016109ea906152be565b612102816125da565b1561211f5760405162461bcd60e51b81526004016109ea90615527565b6004546001600160a01b0316806121485760405162461bcd60e51b81526004016109ea90615619565b61208e73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488285613b72565b60006121716118a7565b61218d5760405162461bcd60e51b81526004016109ea906153a5565b60405163a9059cbb60e01b81526001600160a01b0385169063a9059cbb906121bb9086908690600401614df1565b602060405180830381600087803b1580156121d557600080fd5b505af11580156121e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f57919061494e565b6122156118a7565b6122315760405162461bcd60e51b81526004016109ea906153a5565b61223c816000613cb2565b50565b730efb068354c10c070ddd64a0e8eaf8f054df7e2690565b60006002816006610e46565b60006002816003610e46565b60046122796118a7565b6122c85761228681612592565b6122a25760405162461bcd60e51b81526004016109ea906152be565b6122ab816125da565b156122c85760405162461bcd60e51b81526004016109ea90615527565b6000600260008460068111156122ee57634e487b7160e01b600052602160045260246000fd5b815260208101919091526040016000208054909150600160a01b900460ff161561232a5760405162461bcd60e51b81526004016109ea9061556c565b805460ff60a01b1916600160a01b17815582600681111561235b57634e487b7160e01b600052602160045260246000fd5b6040517fad75709c5a2559beeed6c59693a5ea8701185d51947d3eef38713bb0fe5891e990600090a2505050565b6123916118a7565b6123ad5760405162461bcd60e51b81526004016109ea906153a5565b6001600160a01b0381166123d35760405162461bcd60e51b81526004016109ea90615303565b610f288282613cb2565b6123e56118a7565b6124015760405162461bcd60e51b81526004016109ea906153a5565b6001600160a01b0381166124275760405162461bcd60e51b81526004016109ea90615661565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600060036124556118a7565b6124a45761246281612592565b61247e5760405162461bcd60e51b81526004016109ea906152be565b612487816125da565b156124a45760405162461bcd60e51b81526004016109ea90615527565b600080610b248a8a8b8b8a8a8d612621565b60056124c06118a7565b61250f576124cd81612592565b6124e95760405162461bcd60e51b81526004016109ea906152be565b6124f2816125da565b1561250f5760405162461bcd60e51b81526004016109ea90615527565b61252d7355f2039347564d206ccc6e6ce202853fed386dbf83612f19565b7f70c14fa013d428be746414c53915d6af2495865a3687262ce430049e977d50c58260405161255c91906156be565b60405180910390a15050565b600061258773f1209998bd17eae301a97e3cf7ec17df580e796461291d565b979650505050505050565b6000600260008360068111156125b857634e487b7160e01b600052602160045260246000fd5b81526020810191909152604001600020546001600160a01b0316331492915050565b60006002600083600681111561260057634e487b7160e01b600052602160045260246000fd5b8152602081019190915260400160002054600160a01b900460ff1692915050565b60008080808086600281111561264757634e487b7160e01b600052602160045260246000fd5b141561266c57846126588b8b613d74565b61266291906157ca565b9050849150612679565b6126768a8a613d74565b90505b6126838b8b613d8a565b6000806126a68d73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260006140ad565b915091508a8c141561278257737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03166318cbafe5848c85308e6040518663ffffffff1660e01b81526004016126fa9594939291906156fc565b600060405180830381600087803b15801561271457600080fd5b505af1158015612728573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261275091908101906148bf565b90508060018151811061277357634e487b7160e01b600052603260045260246000fd5b60200260200101519550612811565b6000479050737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663791ac947858d86308f6040518663ffffffff1660e01b81526004016127cf9594939291906156fc565b600060405180830381600087803b1580156127e957600080fd5b505af11580156127fd573d6000803e3d6000fd5b50505050804761280d91906157ca565b9650505b600088600281111561283357634e487b7160e01b600052602160045260246000fd5b1461285f5761284c6128458b886157ca565b8890613d74565b935061285884876157ca565b9450612863565b8594505b5050509750975097945050505050565b7f8d4e5e4cf68c4b7be730141ed4b1c725966c0e1df450c1a01b965afa060fa3e08761289f57336128a1565b305b876128ac57856128af565b60005b886128bb5760006128bd565b865b886128f3576001600160a01b03888116146128d857876128ee565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485b6128f6565b60005b87878760405161290c9796959493929190614d89565b60405180910390a150505050505050565b3660008037600080366000845af43d6000803e80801561293c573d6000f35b3d6000fd5b818061296d5750600281600281111561296a57634e487b7160e01b600052602160045260246000fd5b14155b610f285760405162461bcd60e51b81526004016109ea90615253565b6000806000806129998c8b613d8a565b6001600160a01b038b811614156129c5575073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486129c8565b50895b85612b55576000806129dc8e8460006140ad565b9092509050737a250d5630b4cf539739df2c5dacb4c659f2488d6338ed17396000896002811115612a1d57634e487b7160e01b600052602160045260246000fd5b14612a28578d612a32565b612a328c8f6157ca565b8d85308e6040518663ffffffff1660e01b8152600401612a569594939291906156fc565b600060405180830381600087803b158015612a7057600080fd5b505af1158015612a84573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612aac91908101906148bf565b905080600181518110612acf57634e487b7160e01b600052603260045260246000fd5b6020026020010151955060016002811115612afa57634e487b7160e01b600052602160045260246000fd5b876002811115612b1a57634e487b7160e01b600052602160045260246000fd5b1415612b4757612b34612b2d8c886157ca565b8b90613d74565b9450612b4085876157ca565b9350612b4e565b8994508593505b5050612e32565b600080612b788e73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc260006140ad565b9092509050737a250d5630b4cf539739df2c5dacb4c659f2488d6338ed17396000896002811115612bb957634e487b7160e01b600052602160045260246000fd5b14612bc4578d612bce565b612bce8c8f6157ca565b60028a6002811115612bf057634e487b7160e01b600052602160045260246000fd5b14612bfc576001612bfe565b8c5b85308e6040518663ffffffff1660e01b8152600401612c219594939291906156fc565b600060405180830381600087803b158015612c3b57600080fd5b505af1158015612c4f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612c7791908101906148bf565b905080600181518110612c9a57634e487b7160e01b600052603260045260246000fd5b60200260200101519450612cc473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28460006140ad565b9092509050737a250d5630b4cf539739df2c5dacb4c659f2488d6338ed17396002896002811115612d0557634e487b7160e01b600052602160045260246000fd5b14612d105786612d1a565b612d1a8c886157ca565b8d85308e6040518663ffffffff1660e01b8152600401612d3e9594939291906156fc565b600060405180830381600087803b158015612d5857600080fd5b505af1158015612d6c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612d9491908101906148bf565b905080600181518110612db757634e487b7160e01b600052603260045260246000fd5b6020026020010151955060016002811115612de257634e487b7160e01b600052602160045260246000fd5b876002811115612e0257634e487b7160e01b600052602160045260246000fd5b1415612e2857612e15612b2d8c886157ca565b9450612e2185876157ca565b9350612e2f565b8994508593505b50505b612eb18d8d8d6002896002811115612e5a57634e487b7160e01b600052602160045260246000fd5b14612e93576001896002811115612e8157634e487b7160e01b600052602160045260246000fd5b14612e8c578f612e8e565b845b612ea9565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25b8e8789614263565b6001600160a01b038d163014801590612ed357506001600160a01b038b811614155b15612ee357612ee3818e84613b72565b5050509998505050505050505050565b612efd8282613329565b610f285760405162461bcd60e51b81526004016109ea906150d2565b6000826001600160a01b031682604051612f3290614d58565b60006040518083038185875af1925050503d8060008114612f6f576040519150601f19603f3d011682016040523d82523d6000602084013e612f74565b606091505b505090508061208e573d6000803e3d6000fd5b600080846001600160a01b03166323b872dd60e01b853086604051602401612fb193929190614dcd565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051612fef9190614cf6565b6000604051808303816000865af19150503d806000811461302c576040519150601f19603f3d011682016040523d82523d6000602084013e613031565b606091505b509150915081801561305b57508051158061305b57508080602001905181019061305b919061494e565b611be55760405162461bcd60e51b81526004016109ea9061515f565b6040805160028082526060820183526000928392839283928392919060208301908036833701905050905073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2816000815181106130d857634e487b7160e01b600052603260045260246000fd5b6001600160a01b0392831660209182029290920101528c811614156131555773a0b86991c6218b36c1d19d4a2e9eb0ce3606eb488160018151811061312d57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b0316815250503091506131a7565b8b8160018151811061317757634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b031681525050876131a257336131a4565b305b91505b604080516002808252606082018352600092602083019080368337019050509050737a250d5630b4cf539739df2c5dacb4c659f2488d637ff36ab560018a600281111561320457634e487b7160e01b600052602160045260246000fd5b1415613210578d61321a565b61321a898f6157ca565b8d85878f6040518663ffffffff1660e01b815260040161323d94939291906156c7565b6000604051808303818588803b15801561325657600080fd5b505af115801561326a573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f1916820160405261329391908101906148bf565b9050806001815181106132b657634e487b7160e01b600052603260045260246000fd5b60200260200101519550600160028111156132e157634e487b7160e01b600052602160045260246000fd5b88600281111561330157634e487b7160e01b600052602160045260246000fd5b14156133145761284c6128458c886157ca565b50939b8c9b5094995093975050505050505050565b600080604051806104c001604052806104928152602001615878610492913960405161335d91908590600090602001614d12565b60408051601f19818403018152919052805160209091012090506000805b600a81101561341a576040516133b9907ffffc00c80b0000007f73004edb00094cad80626d8d00000000000000000000009083908690602001614cc0565b6040516020818303038152906040528051906020012060001c9150856001600160a01b0316826001600160a01b031614156133fa5760019350505050611de5565b806134048161580d565b91505080806134129061580d565b91505061337b565b50600095945050505050565b60606044825111801561346c57508151600160fb1b90839060009061345b57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916145b80156134ad5750815160c360f81b908390600190811061349c57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916145b80156134ee57508151607960f81b90839060029081106134dd57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916145b801561352f57508151600560fd1b908390600390811061351e57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916145b156136415760006004835161354491906157ca565b6001600160401b0381111561356957634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613593576020820181803683370190505b50905060045b8351811015613624578381815181106135c257634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b031916826135dd6004846157ca565b815181106135fb57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053508061361c8161580d565b915050613599565b50808060200190518101906136399190614b2e565b91505061366c565b50604080518082019091526012815271286e6f2072657665727420726561736f6e2960701b60208201525b919050565b600281600281111561369357634e487b7160e01b600052602160045260246000fd5b141561223c5760405162461bcd60e51b81526004016109ea906151f6565b6000806001600160a01b03801683604001516001600160a01b0316146136db5782604001516136f1565b73a0b86991c6218b36c1d19d4a2e9eb0ce3606eb485b905061370583602001518460800151613d8a565b600061371b8460200151838661012001516140ad565b5090506000826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161374c9190614d5b565b60206040518083038186803b15801561376457600080fd5b505afa158015613778573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061379c9190614b8b565b9050737a250d5630b4cf539739df2c5dacb4c659f2488d635c11d795600087610140015160028111156137df57634e487b7160e01b600052602160045260246000fd5b146137ee578660800151613802565b8660e00151876080015161380291906157ca565b8760a0015185308a61010001516040518663ffffffff1660e01b815260040161382f9594939291906156fc565b600060405180830381600087803b15801561384957600080fd5b505af115801561385d573d6000803e3d6000fd5b50506040516370a0823160e01b81528392506001600160a01b03861691506370a082319061388f903090600401614d5b565b60206040518083038186803b1580156138a757600080fd5b505afa1580156138bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138df9190614b8b565b6138e991906157ca565b8551909450600092506001600160a01b0316301480159150613919575060408401516001600160a01b0390811614155b15613aa25783516040516370a0823160e01b81526000916001600160a01b038516916370a082319161394d91600401614d5b565b60206040518083038186803b15801561396557600080fd5b505afa158015613979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061399d9190614b8b565b85519091506139ee908490600188610140015160028111156139cf57634e487b7160e01b600052602160045260246000fd5b146139da57866139e9565b60e08801516139e990886157ca565b613b72565b84516040516370a0823160e01b815282916001600160a01b038616916370a0823191613a1c91600401614d5b565b60206040518083038186803b158015613a3457600080fd5b505afa158015613a48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a6c9190614b8b565b613a7691906157ca565b9150508360c00151811015613a9d5760405162461bcd60e51b81526004016109ea906155af565b613ae6565b60018461014001516002811115613ac957634e487b7160e01b600052602160045260246000fd5b14613ad45782613ae3565b60e0840151613ae390846157ca565b90505b835160208501516040860151613b4092919060018861014001516002811115613b1f57634e487b7160e01b600052602160045260246000fd5b14613b2e578760200151613b30565b855b8860600151868a60e00151614263565b5050919050565b6000613b6673f1209998bd17eae301a97e3cf7ec17df580e796461291d565b98975050505050505050565b600080846001600160a01b031663a9059cbb60e01b8585604051602401613b9a929190614df1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613bd89190614cf6565b6000604051808303816000865af19150503d8060008114613c15576040519150601f19603f3d011682016040523d82523d6000602084013e613c1a565b606091505b5091509150818015613c44575080511580613c44575080806020019051810190613c44919061494e565b611be55760405162461bcd60e51b81526004016109ea90615424565b3330148015613c8557506007546001600160e01b031982811661010090920460e01b16145b613ca15760405162461bcd60e51b81526004016109ea9061518c565b506007805464ffffffff0019169055565b600060026000846006811115613cd857634e487b7160e01b600052602160045260246000fd5b8152602081019190915260400160002080549091506001600160a01b0383811691161461208e5780546001600160a01b0319166001600160a01b038316178155826006811115613d3857634e487b7160e01b600052602160045260246000fd5b7f40ab465936efb8324cf37e3a29170c60d9b81de43af89693ce9d92c761e42adc83604051613d679190614d5b565b60405180910390a2505050565b6000818310613d835781610f6b565b5090919050565b604051636eb1769f60e11b815281906001600160a01b0384169063dd62ed3e90613dce903090737a250d5630b4cf539739df2c5dacb4c659f2488d90600401614d6f565b60206040518083038186803b158015613de657600080fd5b505afa158015613dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e1e9190614b8b565b1015610f2857600080836001600160a01b031663095ea7b360e01b737a250d5630b4cf539739df2c5dacb4c659f2488d6000604051602401613e61929190614df1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613e9f9190614cf6565b6000604051808303816000865af19150503d8060008114613edc576040519150601f19603f3d011682016040523d82523d6000602084013e613ee1565b606091505b5091509150836001600160a01b031663095ea7b360e01b737a250d5630b4cf539739df2c5dacb4c659f2488d600019604051602401613f21929190614df1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051613f5f9190614cf6565b6000604051808303816000865af19150503d8060008114613f9c576040519150601f19603f3d011682016040523d82523d6000602084013e613fa1565b606091505b5090925090508161406c57836001600160a01b031663095ea7b360e01b737a250d5630b4cf539739df2c5dacb4c659f2488d85604051602401613fe5929190614df1565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516140239190614cf6565b6000604051808303816000865af19150503d8060008114614060576040519150601f19603f3d011682016040523d82523d6000602084013e614065565b606091505b5090925090505b818015614091575080511580614091575080806020019051810190614091919061494e565b610cdf5760405162461bcd60e51b81526004016109ea90615452565b6060806000836140be5760026140c1565b60035b60ff1690506000816001600160401b038111156140ee57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015614117578160200160208202803683370190505b509050868160008151811061413c57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505084156141b95773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061419857634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b0316815250505b85816141c66001856157ca565b815181106141e457634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505080826001600160401b0381111561422b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015614254578160200160208202803683370190505b50935093505050935093915050565b7f8d4e5e4cf68c4b7be730141ed4b1c725966c0e1df450c1a01b965afa060fa3e08787878787878760405161290c9796959493929190614d89565b60408051808201909152600081526060602082015290565b60006142c96142c48461578b565b615738565b90508281528383830111156142dd57600080fd5b610f6b8360208301846157e1565b80356003811061366c57600080fd5b80356007811061366c57600080fd5b80356001600160601b038116811461366c57600080fd5b600060208284031215614331578081fd5b8135610f6b81615854565b60006020828403121561434d578081fd5b8151610f6b81615854565b60008060006060848603121561436c578182fd5b833561437781615854565b9250602084013561438781615854565b929592945050506040919091013590565b600080604083850312156143aa578182fd5b82356143b581615854565b946020939093013593505050565b600080600080606085870312156143d8578182fd5b84356143e381615854565b93506020850135925060408501356001600160401b0380821115614405578384fd5b818701915087601f830112614418578384fd5b813581811115614426578485fd5b886020828501011115614437578485fd5b95989497505060200194505050565b60008060408385031215614458578182fd5b823561446381615854565b9150602083013561447381615854565b809150509250929050565b60008060008060808587031215614493578182fd5b843561449e81615854565b935060208501356144ae81615854565b925060408501356144be81615854565b9396929550929360600135925050565b600080600080608085870312156144e3578182fd5b84356144ee81615854565b966020860135965060408601359560600135945092505050565b600080600080600060a0868803121561451f578283fd5b853561452a81615854565b945060208601359350604086013592506060860135915061454d608087016142eb565b90509295509295909350565b600080600080600060a08688031215614570578283fd5b853561457b81615854565b97602087013597506040870135966060810135965060800135945092505050565b60008060008060008060c087890312156145b4578384fd5b86356145bf81615854565b9550602087013594506040870135935060608701359250608087013591506145e960a088016142eb565b90509295509295509295565b600080600080600080600060e0888a03121561460f578485fd5b873561461a81615854565b96506020880135955060408801359450606088013593506080880135925060a0880135915061464b60c089016142eb565b905092959891949750929550565b6000602080838503121561466b578182fd5b82516001600160401b0380821115614681578384fd5b818501915085601f830112614694578384fd5b81516146a26142c482615768565b81815284810190848601875b848110156147325781518701604080601f19838f030112156146ce578a8bfd5b6146d781615738565b8a8301516146e481615869565b815282820151898111156146f6578c8dfd5b8084019350508d603f84011261470a578b8cfd5b61471a8e8c8501518486016142b6565b818c01528652505092870192908701906001016146ae565b50909998505050505050505050565b60008060208385031215614753578182fd5b82356001600160401b0380821115614769578384fd5b818501915085601f83011261477c578384fd5b81358181111561478a578485fd5b866020808302850101111561479d578485fd5b60209290920196919550909350505050565b600060208083850312156147c1578182fd5b82356001600160401b03808211156147d7578384fd5b818501915085601f8301126147ea578384fd5b81356147f86142c482615768565b81815284810190848601875b848110156147325781358701606080601f19838f03011215614824578a8bfd5b61482d81615738565b8a83013561483a81615854565b81526040614849848201614309565b828d015291830135918983111561485e578c8dfd5b82840193508e603f850112614871578c8dfd5b8b84013592506148836142c48461578b565b8381528f82858701011115614896578d8efd5b838286018e8301379283018c018d90528101919091528552509287019290870190600101614804565b600060208083850312156148d1578182fd5b82516001600160401b038111156148e6578283fd5b8301601f810185136148f6578283fd5b80516149046142c482615768565b8181528381019083850185840285018601891015614920578687fd5b8694505b83851015614942578051835260019490940193918501918501614924565b50979650505050505050565b60006020828403121561495f578081fd5b8151610f6b81615869565b60008060006060848603121561436c578081fd5b600080600080600080600060e0888a031215614998578081fd5b87356149a381615854565b965060208801356149b381615854565b955060408801359450606088013593506080880135925060a0880135915060c08801356149df81615869565b8091505092959891949750929550565b600080600080600080600080610100898b031215614a0b578182fd5b8835614a1681615854565b97506020890135614a2681615854565b965060408901359550606089013594506080890135935060a0890135925060c0890135614a5281615869565b9150614a6060e08a016142eb565b90509295985092959890939650565b60008060008060008060008060006101208a8c031215614a8d578283fd5b8935614a9881615854565b985060208a0135614aa881615854565b975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135614adb81615869565b9150614aea6101008b016142eb565b90509295985092959850929598565b600060208284031215614b0a578081fd5b610f6b826142fa565b60008060408385031215614b25578182fd5b614463836142fa565b600060208284031215614b3f578081fd5b81516001600160401b03811115614b54578182fd5b8201601f81018413614b64578182fd5b610f57848251602084016142b6565b600060208284031215614b84578081fd5b5035919050565b600060208284031215614b9c578081fd5b5051919050565b6000815180845260208085019450808401835b83811015614bdb5781516001600160a01b031687529582019590820190600101614bb6565b509495945050505050565b6000815180845260208085019450808401835b83811015614bdb578151151587529582019590820190600101614bf9565b6000815180845260208085018081965082840281019150828601855b85811015614c5d578284038952614c4b848351614c94565b98850198935090840190600101614c33565b5091979650505050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452614cac8160208601602086016157e1565b601f01601f19169290920160200192915050565b6affffffffffffffffffffff199390931683526015830191909152603582015260550190565b6000828483379101908152919050565b60008251614d088184602087016157e1565b9190910192915050565b60008451614d248184602089016157e1565b60609490941b6bffffffffffffffffffffffff19169190930190815263ffffffff1991909116601482015260300192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03978816815295871660208701529386166040860152919094166060840152608083019390935260a082019290925260c081019190915260e00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060018060a01b038616825284602083015260806040830152614e316080830185614c94565b82810360608401526125878185614c94565b600060408252614e566040830185614be6565b828103602084015261188f8185614c17565b600060608252614e7b6060830186614be6565b8281036020840152614e8d8186614c17565b9150508215156040830152949350505050565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614f0557888303603f190185528151805115158452870151878401879052614ef287850182614c94565b9588019593505090860190600101614ec4565b509098975050505050505050565b602080825281810183905260009060408084018583028501820187855b88811015614f0557878303603f190184528135368b9003605e19018112614f55578788fd5b8a0160608135614f6481615854565b6001600160a01b031685526001600160601b03614f82838a01614309565b168886015286820135601e19833603018112614f9c57898afd5b820180356001600160401b03811115614fb3578a8bfd5b803603841315614fc1578a8bfd5b8289880152614fd5838801828c8501614c6a565b978a019796505050928701925050600101614f30565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015614f0557888303603f19018552815180516001600160a01b03168452878101516001600160601b031688850152860151606087850181905261505781860183614c94565b96890196945050509086019060010161500f565b901515815260200190565b6000861515825260018060a01b038616602083015284604083015260a060608301526150a560a0830185614c94565b8281036080840152613b668185614c94565b6000831515825260406020830152610f576040830184614c94565b6020808252603a908201527f436f756c64206e6f74207265736f6c766520736d6172742077616c6c6574207560408201527f73696e672070726f7669646564207369676e696e67206b65792e000000000000606082015260800190565b602080825260169082015275496e76616c69642063616c6c2064657465637465642160501b604082015260600190565b6020808252601390820152722a3930b739b332b91034b7103330b4b632b21760691b604082015260600190565b60208082526044908201527f45787465726e616c206163636f756e7473206f7220756e617070726f7665642060408201527f696e7465726e616c2066756e6374696f6e732063616e6e6f742063616c6c20746060820152633434b99760e11b608082015260a00190565b6020808252603e908201527f43616e6e6f742074616b6520746f6b656e2d666f722d746f6b656e206665652060408201527f696e204574686572207769746820666565206f6e207472616e736665722e0000606082015260800190565b60208082526045908201527f43616e6e6f742074616b6520746f6b656e2d666f722d746f6b656e206665652060408201527f696e20457468657220756e6c65737320726f75746564207468726f75676820456060820152643a3432b91760d91b608082015260a00190565b60208082526025908201527f43616c6c657220646f6573206e6f7420686176652061207265717569726564206040820152643937b6329760d91b606082015260800190565b60208082526017908201527f4d75737420737570706c7920616e206163636f756e742e000000000000000000604082015260600190565b60208082526045908201527f54776f537465704f776e61626c653a2063757272656e74206f776e6572206d7560408201527f7374207365742063616c6c6572206173206e657720706f74656e7469616c206f6060820152643bb732b91760d91b608082015260a00190565b60208082526028908201527f54776f537465704f776e61626c653a2063616c6c6572206973206e6f74207468604082015267329037bbb732b91760c11b606082015260800190565b60208082526017908201527f496e76616c696420696d706c656d656e746174696f6e2e000000000000000000604082015260600190565b6020808252601490820152732a3930b739b332b91037baba103330b4b632b21760611b604082015260600190565b60208082526029908201527f546f6b656e20617070726f76616c20666f7220556e697377617020726f75746560408201526839103330b4b632b21760b91b606082015260800190565b60208082526027908201527f4e6f20446169207072696d61727920726563697069656e742063757272656e74604082015266363c9039b2ba1760c91b606082015260800190565b60208082526025908201527f526f6c6520696e207175657374696f6e20697320616c726561647920756e70616040820152643ab9b2b21760d91b606082015260800190565b60208082526025908201527f526f6c6520696e207175657374696f6e2069732063757272656e746c792070616040820152643ab9b2b21760d91b606082015260800190565b60208082526023908201527f526f6c6520696e207175657374696f6e20697320616c7265616479207061757360408201526232b21760e91b606082015260800190565b60208082526044908201527f526563656976656420746f6b656e20616d6f756e74206166746572207472616e60408201527f7366657220666565206973206c657373207468616e2071756f74656420616d6f6060820152633ab73a1760e11b608082015260a00190565b60208082526028908201527f4e6f2055534443207072696d61727920726563697069656e742063757272656e6040820152673a363c9039b2ba1760c11b606082015260800190565b60208082526038908201527f54776f537465704f776e61626c653a206e657720706f74656e7469616c206f7760408201527f6e657220697320746865207a65726f20616464726573732e0000000000000000606082015260800190565b90815260200190565b6000858252608060208301526156e06080830186614ba3565b6001600160a01b03949094166040830152506060015292915050565b600086825285602083015260a0604083015261571b60a0830186614ba3565b6001600160a01b0394909416606083015250608001529392505050565b604051601f8201601f191681016001600160401b03811182821017156157605761576061583e565b604052919050565b60006001600160401b038211156157815761578161583e565b5060209081020190565b60006001600160401b038211156157a4576157a461583e565b50601f01601f191660200190565b600082198211156157c5576157c5615828565b500190565b6000828210156157dc576157dc615828565b500390565b60005b838110156157fc5781810151838201526020016157e4565b83811115610cdf5750506000910152565b600060001982141561582157615821615828565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461223c57600080fd5b801515811461223c57600080fdfe60806040526040516104423803806104428339818101604052602081101561002657600080fd5b810190808051604051939291908464010000000082111561004657600080fd5b90830190602082018581111561005b57600080fd5b825164010000000081118282018810171561007557600080fd5b82525081516020918201929091019080838360005b838110156100a257818101518382015260200161008a565b50505050905090810190601f1680156100cf5780820380516001836020036101000a031916815260200191505b5060405250505060006100e661019e60201b60201c565b6001600160a01b0316826040518082805190602001908083835b6020831061011f5780518252601f199092019160209182019101610100565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d806000811461017f576040519150601f19603f3d011682016040523d82523d6000602084013e610184565b606091505b5050905080610197573d6000803e3d6000fd5b50506102be565b60405160009081906060906e26750c571ce882b17016557279adaa9083818181855afa9150503d80600081146101f0576040519150601f19603f3d011682016040523d82523d6000602084013e6101f5565b606091505b509150915081819061029f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561026457818101518382015260200161024c565b50505050905090810190601f1680156102915780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508080602001905160208110156102b557600080fd5b50519392505050565b610175806102cd6000396000f3fe608060405261001461000f610016565b61011c565b005b60405160009081906060906e26750c571ce882b17016557279adaa9083818181855afa9150503d8060008114610068576040519150601f19603f3d011682016040523d82523d6000602084013e61006d565b606091505b50915091508181906100fd5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156100c25781810151838201526020016100aa565b50505050905090810190601f1680156100ef5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5080806020019051602081101561011357600080fd5b50519392505050565b3660008037600080366000845af43d6000803e80801561013b573d6000f35b3d6000fdfea265627a7a7231582020202020202055706772616465426561636f6e50726f7879563120202020202064736f6c634300050b003200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000024c4d66de8000000000000000000000000a2646970667358221220784b1cc3f6622b5c7aae2f03aa8870aed35115d5feb5040157029b0dff2d8f2364736f6c63430008010033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c982ee89bc9395c8bb470f9816bee3a257bb1e9b
-----Decoded View---------------
Arg [0] : actionRegistryAddress (address): 0xc982eE89BC9395c8bb470F9816bEe3a257bB1E9B
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000c982ee89bc9395c8bb470f9816bee3a257bb1e9b
Deployed Bytecode Sourcemap
16498:67839:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21759:36;21773:10;21785:9;21759:36;;;;;;;:::i;:::-;;;;;;;;16498:67839;;;;;47742:165;;;;;;;;;;-1:-1:-1;47742:165:0;;;;;:::i;:::-;;:::i;:::-;;56649:102;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47251:287;;;;;;;;;;-1:-1:-1;47251:287:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;39514:867::-;;;;;;;;;;-1:-1:-1;39514:867:0;;;;;:::i;:::-;;:::i;21483:49::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;35348:328::-;;;;;;:::i;:::-;;:::i;36626:827::-;;;;;;;;;;-1:-1:-1;36626:827:0;;;;;:::i;:::-;;:::i;2971:90::-;;;;;;;;;;;;;:::i;43385:417::-;;;;;;;;;;-1:-1:-1;43385:417:0;;;;;:::i;:::-;;:::i;49020:276::-;;;;;;;;;;-1:-1:-1;49020:276:0;;;;;:::i;:::-;;:::i;55227:142::-;;;;;;;;;;;;;:::i;32761:993::-;;;;;;;;;;-1:-1:-1;32761:993:0;;;;;:::i;:::-;;:::i;52633:160::-;;;;;;;;;;;;;:::i;55552:140::-;;;;;;;;;;;;;:::i;32264:491::-;;;;;;;;;;-1:-1:-1;32264:491:0;;;;;:::i;:::-;;:::i;34314:760::-;;;;;;:::i;:::-;;:::i;45842:215::-;;;;;;;;;;-1:-1:-1;45842:215:0;;;;;:::i;:::-;;:::i;54855:187::-;;;;;;;;;;;;;:::i;33760:238::-;;;;;;;;;;-1:-1:-1;33760:238:0;;;;;:::i;:::-;;:::i;51916:230::-;;;;;;;;;;-1:-1:-1;51916:230:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;54722:127::-;;;;;;;;;;;;;:::i;25358:2683::-;;;;;;;;;;-1:-1:-1;25358:2683:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;22416:1251::-;;;;;;;;;;-1:-1:-1;22416:1251:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;48110:163::-;;;;;;;;;;-1:-1:-1;48110:163:0;;;;;:::i;:::-;;:::i;3219:298::-;;;;;;;;;;;;;:::i;36326:294::-;;;;;;;;;;-1:-1:-1;36326:294:0;;;;;:::i;:::-;;:::i;2058:73::-;;;;;;;;;;;;;:::i;2400:86::-;;;;;;;;;;;;;:::i;40387:874::-;;;;;;;;;;-1:-1:-1;40387:874:0;;;;;:::i;:::-;;:::i;37459:1197::-;;;;;;;;;;-1:-1:-1;37459:1197:0;;;;;:::i;:::-;;:::i;35682:638::-;;;;;;;;;;-1:-1:-1;35682:638:0;;;;;:::i;:::-;;:::i;55922:354::-;;;;;;;;;;;;;:::i;42067:433::-;;;;;;;;;;-1:-1:-1;42067:433:0;;;;;:::i;:::-;;:::i;24499:853::-;;;;;;;;;;-1:-1:-1;24499:853:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;34004:304::-;;;;;;;;;;-1:-1:-1;34004:304:0;;;;;:::i;35080:262::-;;;;;;:::i;51051:109::-;;;;;;;;;;-1:-1:-1;51051:109:0;;;;;:::i;:::-;;:::i;50697:111::-;;;;;;;;;;-1:-1:-1;50697:111:0;;;;;:::i;:::-;;:::i;28047:1071::-;;;;;;;;;;-1:-1:-1;28047:1071:0;;;;;:::i;:::-;;:::i;45133:454::-;;;;;;;;;;-1:-1:-1;45133:454:0;;;;;:::i;:::-;;:::i;53650:182::-;;;;;;;;;;;;;:::i;31007:869::-;;;;;;;;;;-1:-1:-1;31007:869:0;;;;;:::i;:::-;;:::i;44372:461::-;;;;;;;;;;-1:-1:-1;44372:461:0;;;;;:::i;:::-;;:::i;46533:247::-;;;;;;;;;;-1:-1:-1;46533:247:0;;;;;:::i;:::-;;:::i;50046:98::-;;;;;;;;;;-1:-1:-1;50046:98:0;;;;;:::i;:::-;;:::i;56495:148::-;;;;;;;;;;;;;:::i;54129:147::-;;;;;;;;;;;;;:::i;53140:156::-;;;;;;;;;;;;;:::i;48554:285::-;;;;;;;;;;-1:-1:-1;48554:285:0;;;;;:::i;:::-;;:::i;49605:173::-;;;;;;;;;;-1:-1:-1;49605:173:0;;;;;:::i;:::-;;:::i;2619:225::-;;;;;;;;;;-1:-1:-1;2619:225:0;;;;;:::i;:::-;;:::i;38662:846::-;;;;;;;;;;-1:-1:-1;38662:846:0;;;;;:::i;:::-;;:::i;43808:260::-;;;;;;;;;;-1:-1:-1;43808:260:0;;;;;:::i;:::-;;:::i;31882:376::-;;;;;;;;;;-1:-1:-1;31882:376:0;;;;;:::i;:::-;;:::i;47742:165::-;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;;;;;;;;;47868:21:::1;:33:::0;;-1:-1:-1;;;;;;47868:33:0::1;-1:-1:-1::0;;;;;47868:33:0;;;::::1;::::0;;;::::1;::::0;;47742:165::o;56649:102::-;17428:2;;56649:102::o;47251:287::-;47376:7;47385:23;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;47501:6:::1;-1:-1:-1::0;;;;;47501:11:0::1;47519:6;47527:4;;47501:31;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;47482:50:0;;;;-1:-1:-1;47251:287:0;-1:-1:-1;;;;;47251:287:0:o;39514:867::-;39823:24;39784:19;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;39856:27:::1;::::0;39977:192:::1;40005:5:::0;40019:27:::1;:23:::0;40045:1:::1;40019:27;:::i;:::-;40055:23;40087:17;40113:8;40130:7;40146:16;39977:19;:192::i;:::-;39919:250:::0;;-1:-1:-1;39919:250:0;-1:-1:-1;39919:250:0;-1:-1:-1;40178:197:0::1;40202:4;40215:5;::::0;40229:7:::1;:33;;;;;;-1:-1:-1::0;;;40229:33:0::1;;;;;;;;;;;40279:5;40294:23;40326:19;40354:14;40178:15;:197::i;:::-;84327:1;;39514:867:::0;;;;;;;;;:::o;21483:49::-;;;:::o;35348:328::-;35622:25;35656:14;21584:42;35656:9;:14::i;:::-;35348:328;;;;;;;;:::o;36626:827::-;37060:25;37021:19;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;37094:62:::1;37129:17;37148:7;37094:34;:62::i;:::-;37185:262;37221:4;37235:25;37269:13;37291:31;37331:25;37365:16;37390:8;37407:17;37433:7;37185:19;:262::i;:::-;37165:282:::0;36626:827;-1:-1:-1;;;;;;;;;;36626:827:0:o;2971:90::-;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;3037:18:::1;3030:25:::0;;-1:-1:-1;;;;;;3030:25:0::1;::::0;;2971:90::o;43385:417::-;43537:20;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;43635:54:::1;43654:11;43667:21;43635:18;:54::i;:::-;43756:40;43771:11;43784;43756:14;:40::i;:::-;43385:417:::0;;;;:::o;49020:276::-;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;49083:35:::1;49121:6;:21;49136:4;49128:13;;;;;;-1:-1:-1::0;;;49128:13:0::1;;;;;;;;;49121:21:::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;49121:21:0;49157:23;;49121:21;;-1:-1:-1;;;;49157:23:0;::::1;;;49149:73;;;;-1:-1:-1::0;;;49149:73:0::1;;;;;;;:::i;:::-;49229:31:::0;;-1:-1:-1;;;;49229:31:0::1;::::0;;49285:4;49272:18:::1;::::0;::::1;;;;-1:-1:-1::0;;;49272:18:0::1;;;;;;;;;;::::0;::::1;::::0;;;::::1;2313:1;49020:276:::0;:::o;55227:142::-;55342:21;;-1:-1:-1;;;;;55342:21:0;;55227:142::o;32761:993::-;32995:24;33095:48;33112:5;33119:10;33131:11;33095:16;:48::i;:::-;33152:27;33186:22;33273:164;33301:5;33315:11;33335;33355:17;33381:8;33398:7;33414:16;33273:19;:164::i;:::-;33215:222;;-1:-1:-1;33215:222:0;-1:-1:-1;33215:222:0;-1:-1:-1;33446:186:0;33470:5;;;33498:7;:33;;;;;;-1:-1:-1;;;33498:33:0;;;;;;;;;;;33548:5;33563:11;33583:19;33611:14;33446:15;:186::i;:::-;33701:47;33716:10;33728:19;33701:14;:47::i;:::-;32761:993;;;;;;;;;;:::o;52633:160::-;52694:22;52742:6;52694:22;;52749:29;52742:37;;;;;;;;;;;-1:-1:-1;52742:37:0;:45;-1:-1:-1;;;;;52742:45:0;;52633:160;-1:-1:-1;52633:160:0:o;55552:140::-;55666:20;;-1:-1:-1;;;;;55666:20:0;;55552:140::o;32264:491::-;32701:25;32735:14;21584:42;32735:9;:14::i;:::-;32264:491;;;;;;;;;;;:::o;34314:760::-;34523:25;34602:27;34636:22;34724:161;34757:5;34771:9;34789:17;34815:8;34832:5;34846:7;34862:16;34724:24;:161::i;:::-;34665:220;;-1:-1:-1;34665:220:0;-1:-1:-1;34665:220:0;-1:-1:-1;34894:174:0;34918:5;34932:4;;34945:7;:33;;;;;;-1:-1:-1;;;34945:33:0;;;;;;;;;;;34987:5;35001:9;35019:19;35047:14;34894:15;:174::i;:::-;34314:760;;;;;;;;;:::o;45842:215::-;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;46013:38:::1;46028:9;46039:11;46013:14;:38::i;:::-;45842:215:::0;;:::o;54855:187::-;54926:26;54986:6;54926:26;55001:25;54993:34;;33760:238;33945:24;33978:14;21584:42;33978:9;:14::i;:::-;33760:238;;;;;;:::o;51916:230::-;52039:22;52090:50;52105:11;52118:21;52090:14;:50::i;:::-;52070:70;51916:230;-1:-1:-1;;;51916:230:0:o;54722:127::-;54775:14;54807:6;54775:14;54822:11;54814:20;;25358:2683;25465:16;25483:25;25432:13;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;25570:37:::1;::::0;-1:-1:-1;;;25570:37:0;;25552:15:::1;::::0;-1:-1:-1;;;;;25570:16:0::1;:30;::::0;::::1;::::0;:37:::1;::::0;25601:5;;25570:37:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;25552:55;;25624:10;25616:45;;;;-1:-1:-1::0;;;25616:45:0::1;;;;;;;:::i;:::-;26089:5;:12;-1:-1:-1::0;;;;;26078:24:0::1;;;;;-1:-1:-1::0;;;26078:24:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;26078:24:0::1;;26073:29;;26134:5;:12;-1:-1:-1::0;;;;;26122:25:0::1;;;;;-1:-1:-1::0;;;26122:25:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;26204:16:0::1;:40:::0;;-1:-1:-1;;26204:40:0::1;::::0;::::1;::::0;;26478:71:::1;::::0;26109:38;;-1:-1:-1;;;;;26459:4:0::1;::::0;-1:-1:-1;;;26511:22:0;26478:71:::1;::::0;26535:5;;26478:71:::1;;;:::i;:::-;;::::0;;-1:-1:-1;;26478:71:0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;26478:71:0::1;-1:-1:-1::0;;;;;;26478:71:0;;::::1;::::0;;;::::1;::::0;;;26451:105;;::::1;::::0;26478:71;26451:105:::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26402:154;;;;26626:10;26621:57;;26654:16;26647:23:::0;;-1:-1:-1;;26647:23:0::1;::::0;;26621:57:::1;26768:38;26820:14;26809:49;;;;;;;;;;;;:::i;:::-;26768:90;;26870:9;26865:1171;26889:11;:18;26885:1;:22;26865:1171;;;26923:30;26956:5;26962:1;26956:8;;;;;;-1:-1:-1::0;;;26956:8:0::1;;;;;;;;;;;;;;;26923:41;;27059:11;27071:1;27059:14;;;;;;-1:-1:-1::0;;;27059:14:0::1;;;;;;;;;;;;;;;:17;;;27051:2;27054:1;27051:5;;;;;;-1:-1:-1::0;;;27051:5:0::1;;;;;;;;;;;;;;:25;;;;;;;;;::::0;::::1;27101:11;27113:1;27101:14;;;;;;-1:-1:-1::0;;;27101:14:0::1;;;;;;;;;;;;;;;:25;;;27085:10;27096:1;27085:13;;;;;;-1:-1:-1::0;;;27085:13:0::1;;;;;;;;;;;;;;:41;;;;27223:11;27235:1;27223:14;;;;;;-1:-1:-1::0;;;27223:14:0::1;;;;;;;;;;;;;;;:17;;;27219:810;;;27338:237;27363:10;27362:11;27444;:14;;;27479:11;:17;;;-1:-1:-1::0;;;;;27471:26:0::1;27510:11;:16;;;27539:11;27551:1;27539:14;;;;;;-1:-1:-1::0;;;27539:14:0::1;;;;;;;;;;;;;;;:25;;;27338:237;;;;;;;;;;:::i;:::-;;;;;;;;27219:810;;;27744:176;27768:11;:14;;;27803:11;:17;;;-1:-1:-1::0;;;;;27795:26:0::1;27834:11;:16;;;27863:46;27883:11;27895:1;27883:14;;;;;;-1:-1:-1::0;;;27883:14:0::1;;;;;;;;;;;;;;;:25;;;27863:19;:46::i;:::-;27744:176;;;;;;;;;:::i;:::-;;;;;;;;28014:5;;;27219:810;-1:-1:-1::0;26909:3:0;::::1;::::0;::::1;:::i;:::-;;;;26865:1171;;;;84327:1;;;;25358:2683:::0;;;;:::o;22416:1251::-;22501:16;22519:25;22546:15;22618:16;-1:-1:-1;;;;;22618:30:0;;22649:5;;22618:37;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22605:50;-1:-1:-1;22760:5:0;-1:-1:-1;;;;;22749:24:0;;;;;-1:-1:-1;;;22749:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22749:24:0;-1:-1:-1;22744:29:0;-1:-1:-1;22805:5:0;-1:-1:-1;;;;;22793:25:0;;;;;-1:-1:-1;;;22793:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22780:38;;22979:27;23018:4;-1:-1:-1;;;;;23010:18:0;23070:23;;;23095:5;;23037:72;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;23037:72:0;;;;;;;;;;;;;;-1:-1:-1;;;;;23037:72:0;-1:-1:-1;;;;;;23037:72:0;;;;;;;;;;23010:106;;;;23037:72;23010:106;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22976:140;;;23207:38;23259:14;23248:49;;;;;;;;;;;;:::i;:::-;23207:90;;23309:9;23304:358;23328:11;:18;23324:1;:22;23304:358;;;23446:11;23458:1;23446:14;;;;;;-1:-1:-1;;;23446:14:0;;;;;;;;;;;;;;;:17;;;23438:2;23441:1;23438:5;;;;;;-1:-1:-1;;;23438:5:0;;;;;;;;;;;;;;:25;;;;;;;;;;;23488:11;23500:1;23488:14;;;;;;-1:-1:-1;;;23488:14:0;;;;;;;;;;;;;;;:25;;;23472:10;23483:1;23472:13;;;;;;-1:-1:-1;;;23472:13:0;;;;;;;;;;;;;;:41;;;;23529:11;23541:1;23529:14;;;;;;-1:-1:-1;;;23529:14:0;;;;;;;;;;;;;;;:17;;;23524:131;;23640:5;;23524:131;23348:3;;;;:::i;:::-;;;;23304:358;;;;22416:1251;;;;;;;:::o;48110:163::-;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;48235:20:::1;:32:::0;;-1:-1:-1;;;;;;48235:32:0::1;-1:-1:-1::0;;;;;48235:32:0;;;::::1;::::0;;;::::1;::::0;;48110:163::o;3219:298::-;3290:18;;-1:-1:-1;;;;;3290:18:0;3276:10;:32;3260:135;;;;-1:-1:-1;;;3260:135:0;;;;;;;:::i;:::-;3411:18;3404:25;;-1:-1:-1;;;;;;3404:25:0;;;-1:-1:-1;3464:6:0;;3443:40;;3472:10;;-1:-1:-1;;;;;3464:6:0;;;;3443:40;;;3492:6;:19;;-1:-1:-1;;;;;;3492:19:0;3501:10;3492:19;;;3219:298::o;36326:294::-;36566:25;36600:14;21584:42;36600:9;:14::i;:::-;36326:294;;;;;;;:::o;2058:73::-;2096:7;2119:6;-1:-1:-1;;;;;2119:6:0;2058:73;:::o;2400:86::-;2440:4;2474:6;-1:-1:-1;;;;;2474:6:0;2460:10;:20;;2400:86::o;40387:874::-;40678:25;40633:19;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;40761:27:::1;40795:22:::0;40883:174:::1;40916:5;40930:23;40962:17;40988:8;41005:4;41018:7;41034:16;40883:24;:174::i;:::-;40824:233:::0;;-1:-1:-1;40824:233:0;-1:-1:-1;40824:233:0;-1:-1:-1;41066:189:0::1;41090:4;::::0;;41116:7:::1;:33;;;;;;-1:-1:-1::0;;;41116:33:0::1;;;;;;;;;;;41158:5;41172:23;41204:19;41232:16;41066:15;:189::i;37459:1197::-:0;37910:25;37871:19;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;37944:26:::1;37962:7;37944:17;:26::i;:::-;37999:651;38044:599;;;;;;;;38110:4;-1:-1:-1::0;;;;;38044:599:0::1;;;;;38139:25;-1:-1:-1::0;;;;;38044:599:0::1;;;;;38198:13;-1:-1:-1::0;;;;;38044:599:0::1;;;;;38241:31;38044:599;;;;38318:31;38044:599;;;;38385:25;38044:599;;;;38462:31;38044:599;;;;38520:16;38044:599;;;;38555:8;38044:599;;;;38591:17;38044:599;;;;;;38626:7;38044:599;;;;;;-1:-1:-1::0;;;38044:599:0::1;;;;;;;;;::::0;;37999:36:::1;:651::i;35682:638::-:0;36032:25;36002:19;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;36086:228:::1;36131:5;36145:23;36177:17;36203:33;36245:16;36270:8;36287:4;36300:7;36086:36;:228::i;55922:354::-:0;55989:22;56025:7;56034:23;56077:42;-1:-1:-1;;;;;56061:76:0;:80;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56024:117;;;;56156:2;:29;;;;;56162:10;:17;56183:2;56162:23;56156:29;56148:65;;;;-1:-1:-1;;;56148:65:0;;;;;;;:::i;:::-;56248:10;56237:33;;;;;;;;;;;;:::i;:::-;56220:50;;55922:354;;;:::o;42067:433::-;42233:20;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;42331:54:::1;42350:11;42363:21;42331:18;:54::i;:::-;42452:42;42467:5;42474:11;42487:6;42452:14;:42::i;:::-;42067:433:::0;;;;;:::o;24499:853::-;24572:38;24659:5;:12;-1:-1:-1;;;;;24635:37:0;;;;;-1:-1:-1;;;24635:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;24621:51;;24686:9;24681:447;24705:5;:12;24701:1;:16;24681:447;;;24803:7;24812:23;24839:5;24845:1;24839:8;;;;;;-1:-1:-1;;;24839:8:0;;;;;;;;;;;;;;;:11;;;-1:-1:-1;;;;;24839:16:0;24880:5;24886:1;24880:8;;;;;;-1:-1:-1;;;24880:8:0;;;;;;;;;;;;;;;:14;;;-1:-1:-1;;;;;24872:23:0;24905:5;24911:1;24905:8;;;;;;-1:-1:-1;;;24905:8:0;;;;;;;;;;;;;;;:13;;;24839:80;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24802:117;;;;24945:51;;;;;;;;24968:2;24945:51;;;;;;24984:10;24945:51;;;24928:11;24940:1;24928:14;;;;;;-1:-1:-1;;;24928:14:0;;;;;;;;;;;;;;:68;;;;25010:2;25005:116;;25106:5;;;;25005:116;24681:447;;24719:3;;;;;:::i;:::-;;;;24681:447;;;;25214:29;25257:11;25246:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;25214:55;;25327:16;25321:23;25302:16;25298:2;25294:25;25287:58;51051:109;51110:12;51141:13;51149:4;51141:7;:13::i;:::-;51131:23;51051:109;-1:-1:-1;;51051:109:0:o;50697:111::-;50758:11;50787:15;50797:4;50787:9;:15::i;28047:1071::-;28119:38;28245:43;-1:-1:-1;;;28245:20:0;:43::i;:::-;28297:13;28363:5;:12;-1:-1:-1;;;;;28339:37:0;;;;;-1:-1:-1;;;28339:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;28325:51;;28390:9;28385:473;28409:5;:12;28405:1;:16;28385:473;;;28507:7;28516:23;28543:5;28549:1;28543:8;;;;;;-1:-1:-1;;;28543:8:0;;;;;;;;;;;;;;;:11;;;-1:-1:-1;;;;;28543:16:0;28584:5;28590:1;28584:8;;;;;;-1:-1:-1;;;28584:8:0;;;;;;;;;;;;;;;:14;;;-1:-1:-1;;;;;28576:23:0;28609:5;28615:1;28609:8;;;;;;-1:-1:-1;;;28609:8:0;;;;;;;;;;;;;;;:13;;;28543:80;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28506:117;;;;28649:51;;;;;;;;28672:2;28649:51;;;;;;28688:10;28649:51;;;28632:11;28644:1;28632:14;;;;;;-1:-1:-1;;;28632:14:0;;;;;;;;;;;;;;:68;;;;28714:2;28709:142;;28821:4;28810:15;;28836:5;;;;28709:142;28385:473;;28423:3;;;;;:::i;:::-;;;;28385:473;;;;28870:8;28866:247;;;28971:29;29014:11;29003:23;;;;;;;;:::i;29044:62::-;28047:1071;;;;:::o;45133:454::-;45222:23;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;45333:20:::1;::::0;-1:-1:-1;;;;;45333:20:0::1;45376:30:::0;45360:96:::1;;;;-1:-1:-1::0;;;45360:96:0::1;;;;;;;:::i;:::-;45532:49;17687:42;45553:16;45571:9;45532:14;:49::i;:::-;84327:1;45133:454:::0;;:::o;53650:182::-;53720:25;53778:6;53720:25;53778:6;53785:32;;31007:869;31371:25;31405:62;31440:17;31459:7;31405:34;:62::i;:::-;31542:64;31559:13;31574:10;31586:19;31542:16;:64::i;:::-;31635:235;31663:10;31682:13;31704;31726:19;31754:25;31788:16;31813:8;31830:17;31856:7;31635:19;:235::i;44372:461::-;44463:23;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;44574:21:::1;::::0;-1:-1:-1;;;;;44574:21:0::1;44618:30:::0;44602:97:::1;;;;-1:-1:-1::0;;;44602:97:0::1;;;;;;;:::i;:::-;44776:51;17561:42;44798:16;44816:10;44776:14;:51::i;46533:247::-:0;46655:12;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;46741:33:::1;::::0;-1:-1:-1;;;46741:33:0;;-1:-1:-1;;;;;46741:14:0;::::1;::::0;::::1;::::0;:33:::1;::::0;46756:9;;46767:6;;46741:33:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;50046:98::-:0;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;50112:26:::1;50121:4;50135:1;50112:8;:26::i;:::-;50046:98:::0;:::o;56495:148::-;56594:42;;56495:148::o;54129:147::-;54190:16;54232:6;54190:16;54247:13;54239:22;;53140:156;53200:21;53246:6;53200:21;53261:19;53253:28;;48554:285;48610:11;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;48630:35:::1;48668:6;:21;48683:4;48675:13;;;;;;-1:-1:-1::0;;;48675:13:0::1;;;;;;;;;48668:21:::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;48668:21:0;48705:23;;48668:21;;-1:-1:-1;;;;48705:23:0;::::1;;;48704:24;48696:72;;;;-1:-1:-1::0;;;48696:72:0::1;;;;;;;:::i;:::-;48775:30:::0;;-1:-1:-1;;;;48775:30:0::1;-1:-1:-1::0;;;48775:30:0::1;::::0;;48828:4;48817:16:::1;::::0;::::1;;;;-1:-1:-1::0;;;48817:16:0::1;;;;;;;;;;::::0;::::1;::::0;;;::::1;84327:1;48554:285:::0;;:::o;49605:173::-;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;49693:21:0;::::1;49685:57;;;;-1:-1:-1::0;;;49685:57:0::1;;;;;;;:::i;:::-;49749:23;49758:4;49764:7;49749:8;:23::i;2619:225::-:0;2252:9;:7;:9::i;:::-;2244:62;;;;-1:-1:-1;;;2244:62:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2704:22:0;::::1;2688:112;;;;-1:-1:-1::0;;;2688:112:0::1;;;;;;;:::i;:::-;2809:18;:29:::0;;-1:-1:-1;;;;;;2809:29:0::1;-1:-1:-1::0;;;;;2809:29:0;;;::::1;::::0;;;::::1;::::0;;2619:225::o;38662:846::-;38954:24;38915:19;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;38987:27:::1;39021:22:::0;39108:188:::1;39136:5;39150:23;39182;39214:17;39240:8;39257:7;39273:16;39108:19;:188::i;43808:260::-:0;43886:25;84155:9;:7;:9::i;:::-;84150:171;;84183:13;84191:4;84183:7;:13::i;:::-;84175:63;;;;-1:-1:-1;;;84175:63:0;;;;;;;:::i;:::-;84256:15;84266:4;84256:9;:15::i;:::-;84255:16;84247:66;;;;-1:-1:-1;;;84247:66:0;;;;;;;:::i;:::-;43976:41:::1;18282:42;44005:11;43976:14;:41::i;:::-;44031:31;44050:11;44031:31;;;;;;:::i;:::-;;;;;;;;43808:260:::0;;:::o;31882:376::-;32204:25;32238:14;21584:42;32238:9;:14::i;:::-;31882:376;;;;;;;;;:::o;78807:131::-;78858:12;78903:6;:21;78918:4;78910:13;;;;;;-1:-1:-1;;;78910:13:0;;;;;;;;;78903:21;;;;;;;;;;;-1:-1:-1;78903:21:0;:29;-1:-1:-1;;;;;78903:29:0;78889:10;:43;;;-1:-1:-1;;78807:131:0:o;79176:116::-;79229:11;79258:6;:21;79273:4;79265:13;;;;;;-1:-1:-1;;;79265:13:0;;;;;;;;;79258:21;;;;;;;;;;;-1:-1:-1;79258:21:0;:28;-1:-1:-1;;;79258:28:0;;;;;;-1:-1:-1;;79176:116:0:o;60460:2105::-;60721:24;;;;;60883:7;:33;;;;;;-1:-1:-1;;;60883:33:0;;;;;;;;;;60879:258;;;60989:16;60942:44;:11;60958:27;60942:15;:44::i;:::-;:63;;;;:::i;:::-;60927:79;;61032:16;61015:33;;60879:258;;;61085:44;:11;61101:27;61085:15;:44::i;:::-;61071:58;;60879:258;61223:58;61262:5;61269:11;61223:38;:58::i;:::-;61342:21;61365:24;61393:65;61431:5;18173:42;61446:5;61393:21;:65::i;:::-;61341:117;;;;61567:27;61552:11;:42;61548:572;;;18071:42;-1:-1:-1;;;;;61615:37:0;;61663:11;61676:17;61695:4;61709;61716:8;61615:118;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;61615:118:0;;;;;;;;;;;;:::i;:::-;61605:128;;61761:7;61769:1;61761:10;;;;;;-1:-1:-1;;;61761:10:0;;;;;;;;;;;;;;;61742:29;;61548:572;;;61794:29;61826:21;61794:53;;18071:42;-1:-1:-1;;;;;61856:66:0;;61933:11;61955:17;61983:4;62006;62022:8;61856:183;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62091:21;62067;:45;;;;:::i;:::-;62048:64;;61548:572;;62143:22;62132:7;:33;;;;;;-1:-1:-1;;;62132:33:0;;;;;;;;;;62128:432;;62276:76;62307:36;62326:17;62307:16;:36;:::i;:::-;62276:16;;:20;:76::i;:::-;62259:93;-1:-1:-1;62458:33:0;62259:93;62458:16;:33;:::i;:::-;62436:55;;62128:432;;;62536:16;62514:38;;62128:432;60460:2105;;;;;;;;;;;;;;:::o;77993:571::-;78223:335;78237:12;:41;;78268:10;78237:41;;;78260:4;78237:41;78287:14;:35;;78317:5;78287:35;;;78312:1;78287:35;78331:14;:35;;78364:1;78331:35;;;78348:5;78331:35;78375:10;:107;;-1:-1:-1;;;;;78416:40:0;;;;:65;;78476:5;78416:65;;;17561:42;78416:65;78375:107;;;78403:1;78375:107;78491:14;78514;78537;78223:335;;;;;;;;;;;;:::i;:::-;;;;;;;;77993:571;;;;;;;:::o;83472:364::-;83567:14;83564:1;83561;83548:34;83662:1;83659;83643:14;83640:1;83624:14;83617:5;83604:60;83693:16;83690:1;83687;83672:38;83725:6;83739:38;;;;83805:16;83802:1;83795:27;83739:38;83758:16;83755:1;83748:27;82999:270;83131:17;:45;;;-1:-1:-1;83163:13:0;83152:7;:24;;;;;;-1:-1:-1;;;83152:24:0;;;;;;;;;;;83131:45;83115:148;;;;-1:-1:-1;;;83115:148:0;;;;;;;:::i;62812:4104::-;63187:25;63221:22;63250;63279:21;63387:74;63426:13;63441:19;63387:38;:74::i;:::-;-1:-1:-1;;;;;63515:58:0;;;;63511:173;;;-1:-1:-1;17561:42:0;63511:173;;;-1:-1:-1;63653:23:0;63511:173;63696:26;63692:2682;;63782:21;63805:24;63833:85;63873:13;63889;63904:5;63833:21;:85::i;:::-;63781:137;;-1:-1:-1;63781:137:0;-1:-1:-1;18071:42:0;64021:40;64083:22;64072:7;:33;;;;;;-1:-1:-1;;;64072:33:0;;;;;;;;;;:114;;64167:19;64072:114;;;64117:38;64139:16;64117:19;:38;:::i;:::-;64197:25;64233:4;64256;64272:8;64021:268;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;64021:268:0;;;;;;;;;;;;:::i;:::-;64011:278;;64320:7;64328:1;64320:10;;;;;;-1:-1:-1;;;64320:10:0;;;;;;;;;;;;;;;64300:30;;64356:22;64345:33;;;;;;-1:-1:-1;;;64345:33:0;;;;;;;;;:7;:33;;;;;;-1:-1:-1;;;64345:33:0;;;;;;;;;;64341:414;;;64489:89;64522:45;64542:25;64522:17;:45;:::i;:::-;64489:16;;:20;:89::i;:::-;64472:106;-1:-1:-1;64606:34:0;64472:106;64606:17;:34;:::i;:::-;64589:51;;64341:414;;;64684:16;64667:33;;64728:17;64711:34;;64341:414;63692:2682;;;;;64836:21;64859:24;64887:77;64927:13;18173:42;64950:5;64887:21;:77::i;:::-;64835:129;;-1:-1:-1;64835:129:0;-1:-1:-1;18071:42:0;65068:40;65130:22;65119:7;:33;;;;;;-1:-1:-1;;;65119:33:0;;;;;;;;;;:114;;65214:19;65119:114;;;65164:38;65186:16;65164:19;:38;:::i;:::-;65255:13;65244:7;:24;;;;;;-1:-1:-1;;;65244:24:0;;;;;;;;;;:47;;65290:1;65244:47;;;65271:16;65244:47;65302:4;65325;65341:8;65068:290;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65068:290:0;;;;;;;;;;;;:::i;:::-;65058:300;;65384:7;65392:1;65384:10;;;;;;-1:-1:-1;;;65384:10:0;;;;;;;;;;;;;;;65367:27;;65481:68;18173:42;65520:13;65535:5;65481:21;:68::i;:::-;65463:86;;-1:-1:-1;65463:86:0;-1:-1:-1;18071:42:0;65652:40;65714:13;65703:7;:24;;;;;;-1:-1:-1;;;65703:24:0;;;;;;;;;;:95;;65784:14;65703:95;;;65739:33;65756:16;65739:14;:33;:::i;:::-;65809:25;65845:4;65868;65884:8;65652:249;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65652:249:0;;;;;;;;;;;;:::i;:::-;65642:259;;65932:7;65940:1;65932:10;;;;;;-1:-1:-1;;;65932:10:0;;;;;;;;;;;;;;;65912:30;;65968:22;65957:33;;;;;;-1:-1:-1;;;65957:33:0;;;;;;;;;:7;:33;;;;;;-1:-1:-1;;;65957:33:0;;;;;;;;;;65953:414;;;66101:89;66134:45;66154:25;66134:17;:45;:::i;66101:89::-;66084:106;-1:-1:-1;66218:34:0;66084:106;66218:17;:34;:::i;:::-;66201:51;;65953:414;;;66296:16;66279:33;;66340:17;66323:34;;65953:414;63692:2682;;;66382:320;66401:7;66425:13;66448:23;66491:13;66480:7;:24;;;;;;-1:-1:-1;;;66480:24:0;;;;;;;;;;:141;;66541:22;66530:7;:33;;;;;;-1:-1:-1;;;66530:33:0;;;;;;;;;;:84;;66600:13;66530:84;;;66571:13;66530:84;66480:141;;;18173:42;66480:141;66630:19;66658:14;66681;66382:10;:320::i;:::-;-1:-1:-1;;;;;66723:24:0;;66742:4;66723:24;;;;:93;;-1:-1:-1;;;;;;66758:58:0;;;;;66723:93;66711:200;;;66833:70;66863:13;66879:7;66888:14;66833;:70::i;:::-;62812:4104;;;;;;;;;;;;;;:::o;82292:259::-;82419:50;82434:11;82447:21;82419:14;:50::i;:::-;82403:142;;;;-1:-1:-1;;;82403:142:0;;;;;;;:::i;81557:353::-;81719:7;81732:9;-1:-1:-1;;;;;81732:14:0;81753:11;81732:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81718:51;;;81781:2;81776:129;;81835:16;81832:1;;81814:38;81872:16;81832:1;81862:27;81916:370;82011:12;82025:17;82054:5;-1:-1:-1;;;;;82046:19:0;82097:27;;;82126:4;82140;82147:6;82074:80;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;82074:80:0;;;;;;;;;;;;;;-1:-1:-1;;;;;82074:80:0;-1:-1:-1;;;;;;82074:80:0;;;;;;;;;;82046:115;;;;82074:80;82046:115;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82010:151;;;;82186:7;:57;;;;-1:-1:-1;82198:11:0;;:16;;:44;;;82229:4;82218:24;;;;;;;;;;;;:::i;:::-;82170:110;;;;-1:-1:-1;;;82170:110:0;;;;;;;:::i;58855:1599::-;59312:16;;;59326:1;59312:16;;;;;;;;59114:25;;;;;;;;;;59312:16;59326:1;59312:16;;;;;;;;;;-1:-1:-1;59312:16:0;59288:40;;18173:42;59335:4;59340:1;59335:7;;;;;;-1:-1:-1;;;59335:7:0;;;;;;;;;-1:-1:-1;;;;;59335:15:0;;;:7;;;;;;;;;:15;59361:58;;;;59357:261;;;17561:42;59430:4;59435:1;59430:7;;;;;;-1:-1:-1;;;59430:7:0;;;;;;;;;;;;;;:24;-1:-1:-1;;;;;59430:24:0;;;-1:-1:-1;;;;;59430:24:0;;;;;59485:4;59463:27;;59357:261;;;59523:23;59513:4;59518:1;59513:7;;;;;;-1:-1:-1;;;59513:7:0;;;;;;;;;;;;;;:33;-1:-1:-1;;;;;59513:33:0;;;-1:-1:-1;;;;;59513:33:0;;;;;59569:12;:41;;59600:10;59569:41;;;59592:4;59569:41;59555:55;;59357:261;59732:16;;;59746:1;59732:16;;;;;;;;59705:24;;59732:16;;;;;;;;;;-1:-1:-1;;59705:43:0;-1:-1:-1;18071:42:0;59765:37;59828:22;59817:7;:33;;;;;;-1:-1:-1;;;59817:33:0;;;;;;;;;;;:94;;59900:11;59817:94;;;59860:30;59874:16;59860:11;:30;:::i;:::-;59927:17;59953:4;59966:11;59986:8;59765:236;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59765:236:0;;;;;;;;;;;;:::i;:::-;59755:246;;60028:7;60036:1;60028:10;;;;;;-1:-1:-1;;;60028:10:0;;;;;;;;;;;;;;;60008:30;;60062:22;60051:33;;;;;;-1:-1:-1;;;60051:33:0;;;;;;;;;:7;:33;;;;;;-1:-1:-1;;;60051:33:0;;;;;;;;;;60047:402;;;60195:77;60226:37;60246:17;60226;:37;:::i;60047:402::-;-1:-1:-1;60424:17:0;;;;-1:-1:-1;60377:16:0;;-1:-1:-1;58855:1599:0;;-1:-1:-1;;;;;;;;58855:1599:0:o;79647:1554::-;79756:4;79844:20;79912:28;;;;;;;;;;;;;;;;;79885:135;;;;;79951:21;;21120:58;;21106:77;79885:135;;:::i;:::-;;;;-1:-1:-1;;79885:135:0;;;;;;;;;79867:160;;79885:135;79867:160;;;;;-1:-1:-1;80116:14:0;;80137:958;80169:2;80161:5;:10;80137:958;;;80499:307;;;;18461:94;;80658:5;;80730:12;;80499:307;;;:::i;:::-;;;;;;;;;;;;;80421:400;;;;;;80343:491;;80191:663;;80961:11;-1:-1:-1;;;;;80951:21:0;:6;-1:-1:-1;;;;;80951:21:0;;80947:59;;;80992:4;80985:11;;;;;;;80947:59;81080:7;;;;:::i;:::-;;;;80173;;;;;:::i;:::-;;;;80137:958;;;-1:-1:-1;81190:5:0;;79647:1554;-1:-1:-1;;;;;79647:1554:0:o;30033:968::-;30120:26;30269:2;30249:10;:17;:22;:106;;;;-1:-1:-1;30326:13:0;;-1:-1:-1;;;30343:12:0;30326:10;;30337:1;;30326:13;;-1:-1:-1;;;30326:13:0;;;;;;;;;;;;;-1:-1:-1;;;;;;30326:13:0;:29;30249:106;:146;;;;-1:-1:-1;30366:13:0;;-1:-1:-1;;;30383:12:0;30366:10;;30377:1;;30366:13;;;;-1:-1:-1;;;30366:13:0;;;;;;;;;;;;;-1:-1:-1;;;;;;30366:13:0;:29;30249:146;:186;;;;-1:-1:-1;30406:13:0;;-1:-1:-1;;;30423:12:0;30406:10;;30417:1;;30406:13;;;;-1:-1:-1;;;30406:13:0;;;;;;;;;;;;;-1:-1:-1;;;;;;30406:13:0;:29;30249:186;:226;;;;-1:-1:-1;30446:13:0;;-1:-1:-1;;;30463:12:0;30446:10;;30457:1;;30446:13;;;;-1:-1:-1;;;30446:13:0;;;;;;;;;;;;;-1:-1:-1;;;;;;30446:13:0;:29;30249:226;30237:759;;;30565:30;30628:1;30608:10;:17;:21;;;;:::i;:::-;-1:-1:-1;;;;;30598:32:0;;;;;-1:-1:-1;;;30598:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30598:32:0;-1:-1:-1;30565:65:0;-1:-1:-1;30656:1:0;30639:109;30663:10;:17;30659:1;:21;30639:109;;;30725:10;30736:1;30725:13;;;;;;-1:-1:-1;;;30725:13:0;;;;;;;;;;;;;-1:-1:-1;;;;;;30725:13:0;30698:17;30716:5;30720:1;30716;:5;:::i;:::-;30698:24;;;;;;-1:-1:-1;;;30698:24:0;;;;;;;;;;;;:40;-1:-1:-1;;;;;30698:40:0;;;;;;;;-1:-1:-1;30682:3:0;;;;:::i;:::-;;;;30639:109;;;;30842:17;30831:39;;;;;;;;;;;;:::i;:::-;30816:54;;30237:759;;;;-1:-1:-1;30953:35:0;;;;;;;;;;;;-1:-1:-1;;;30953:35:0;;;;30237:759;30033:968;;;:::o;83275:191::-;83367:13;83356:7;:24;;;;;;-1:-1:-1;;;83356:24:0;;;;;;;;;;;83340:120;;;;-1:-1:-1;;;83340:120:0;;;;;;;:::i;70569:3132::-;70696:25;70730:28;-1:-1:-1;;;;;70768:63:0;;:4;:28;;;-1:-1:-1;;;;;70768:63:0;;:144;;70883:4;:28;;;70768:144;;;17561:42;70768:144;70730:189;;71006:114;71053:4;:18;;;71073:4;:40;;;71006:38;:114::i;:::-;71220:21;71247:116;71287:4;:18;;;71316:13;71332:4;:22;;;71247:21;:116::i;:::-;71219:144;;;71452:42;71497:13;-1:-1:-1;;;;;71497:23:0;;71539:4;71497:56;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71452:101;-1:-1:-1;18071:42:0;71646:69;71742:22;71726:4;:12;;;:38;;;;;;-1:-1:-1;;;71726:38:0;;;;;;;;;;:166;;71852:4;:40;;;71726:166;;;71819:4;:21;;;71776:4;:40;;;:64;;;;:::i;:::-;71903:4;:30;;;71944:4;71967;71983;:13;;;71646:359;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;72036:38:0;;-1:-1:-1;;;72036:38:0;;72077:34;;-1:-1:-1;;;;;;72036:23:0;;;-1:-1:-1;72036:23:0;;:38;;72068:4;;72036:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:75;;;;:::i;:::-;72182:12;;72016:95;;-1:-1:-1;72125:38:0;;-1:-1:-1;;;;;;72182:29:0;72206:4;72182:29;;;;-1:-1:-1;72182:103:0;;-1:-1:-1;72222:28:0;;;;-1:-1:-1;;;;;72222:63:0;;;;;72182:103;72170:1188;;;72458:12;;72422:59;;-1:-1:-1;;;72422:59:0;;72375:44;;-1:-1:-1;;;;;72422:23:0;;;;;:59;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72621:12;;72375:106;;-1:-1:-1;72568:213:0;;72595:13;;72662:22;72646:4;:12;;;:38;;;;;;-1:-1:-1;;;72646:38:0;;;;;;;;;;:124;;72753:17;72646:124;;;72718:21;;;;72698:41;;:17;:41;:::i;:::-;72568:14;:213::i;:::-;72851:12;;72827:37;;-1:-1:-1;;;72827:37:0;;72867:36;;-1:-1:-1;;;;;72827:23:0;;;;;:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:76;;;;:::i;:::-;72794:109;;72170:1188;73042:4;:46;;;73008:30;:80;;72990:188;;;;-1:-1:-1;;;72990:188:0;;;;;;;:::i;:::-;72170:1188;;;73250:22;73234:4;:12;;;:38;;;;;;-1:-1:-1;;;73234:38:0;;;;;;;;;;:116;;73333:17;73234:116;;;73302:21;;;;73282:41;;:17;:41;:::i;:::-;73201:149;;72170:1188;73385:12;;73414:18;;;;73442:28;;;;73366:329;;73385:12;73414:18;73495:22;73479:4;:12;;;:38;;;;;;-1:-1:-1;;;73479:38:0;;;;;;;;;;:107;;73567:4;:18;;;73479:107;;;73535:13;73479:107;73595:4;:24;;;73628:30;73667:4;:21;;;73366:10;:329::i;:::-;70569:3132;;;;;:::o;57926:367::-;58239:25;58273:14;21584:42;58273:9;:14::i;:::-;57926:367;;;;;;;;;;:::o;81207:344::-;81298:12;81312:17;81341:5;-1:-1:-1;;;;;81333:19:0;81384:23;;;81409:2;81413:6;81361:59;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;81361:59:0;;;;;;;;;;;;;;-1:-1:-1;;;;;81361:59:0;-1:-1:-1;;;;;;81361:59:0;;;;;;;;;;81333:94;;;;81361:59;81333:94;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81297:130;;;;81450:7;:57;;;;-1:-1:-1;81462:11:0;;:16;;:44;;;81493:4;81482:24;;;;;;;;;;;;:::i;:::-;81434:111;;;;-1:-1:-1;;;81434:111:0;;;;;;;:::i;29633:392::-;29798:10;29820:4;29798:27;:66;;;;-1:-1:-1;29829:16:0;;-1:-1:-1;;;;;;29829:35:0;;;:16;;;;;;:35;;29798:66;29782:168;;;;-1:-1:-1;;;29782:168:0;;;;;;;:::i;:::-;-1:-1:-1;30003:16:0;29996:23;;-1:-1:-1;;29996:23:0;;;29633:392::o;77305:268::-;77367:35;77405:6;:21;77420:4;77412:13;;;;;;-1:-1:-1;;;77412:13:0;;;;;;;;;77405:21;;;;;;;;;;;-1:-1:-1;77405:21:0;77450:24;;77405:21;;-1:-1:-1;;;;;;77439:35:0;;;77450:24;;77439:35;77435:133;;77485:34;;-1:-1:-1;;;;;;77485:34:0;-1:-1:-1;;;;;77485:34:0;;;;;77546:4;77533:27;;;;;;-1:-1:-1;;;77533:27:0;;;;;;;;;;77552:7;77533:27;;;;;;:::i;:::-;;;;;;;;77305:268;;;:::o;15308:100::-;15366:7;15393:1;15389;:5;:13;;15401:1;15389:13;;;-1:-1:-1;15397:1:0;;15308:100;-1:-1:-1;15308:100:0:o;56757:1163::-;56873:56;;-1:-1:-1;;;56873:56:0;;56932:6;;-1:-1:-1;;;;;56873:15:0;;;;;:56;;56897:4;;18071:42;;56873:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:65;56869:1046;;;57024:12;57038:17;57067:5;-1:-1:-1;;;;;57059:19:0;57124:22;;;18071:42;57182:1;57089:106;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;57089:106:0;;;;;;;;;;;;;;-1:-1:-1;;;;;57089:106:0;-1:-1:-1;;;;;;57089:106:0;;;;;;;;;;57059:145;;;;57089:106;57059:145;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57023:181;;;;57321:5;-1:-1:-1;;;;;57313:19:0;57378:22;;;18071:42;-1:-1:-1;;57343:113:0;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;57343:113:0;;;;;;;;;;;;;;-1:-1:-1;;;;;57343:113:0;-1:-1:-1;;;;;;57343:113:0;;;;;;;;;;57313:152;;;;57343:113;57313:152;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57295:170:0;;-1:-1:-1;57295:170:0;-1:-1:-1;57295:170:0;57476:283;;57608:5;-1:-1:-1;;;;;57600:19:0;57669:22;;;18071:42;57719:6;57632:106;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;57632:106:0;;;;;;;;;;;;;;-1:-1:-1;;;;;57632:106:0;-1:-1:-1;;;;;;57632:106:0;;;;;;;;;;57600:149;;;;57632:106;57600:149;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57582:167:0;;-1:-1:-1;57582:167:0;-1:-1:-1;57476:283:0;57787:7;:57;;;;-1:-1:-1;57799:11:0;;:16;;:44;;;57830:4;57819:24;;;;;;;;;;;;:::i;:::-;57769:138;;;;-1:-1:-1;;;57769:138:0;;;;;;;:::i;82557:436::-;82673:16;82691;82716:18;82737:17;:25;;82761:1;82737:25;;;82757:1;82737:25;82716:46;;;;82769:21;82807:10;-1:-1:-1;;;;;82793:25:0;;;;;-1:-1:-1;;;82793:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82793:25:0;;82769:49;;82835:5;82825:4;82830:1;82825:7;;;;;;-1:-1:-1;;;82825:7:0;;;;;;;;;;;;;;:15;-1:-1:-1;;;;;82825:15:0;;;-1:-1:-1;;;;;82825:15:0;;;;;82853:17;82849:55;;;18173:42;82881:4;82886:1;82881:7;;;;;;-1:-1:-1;;;82881:7:0;;;;;;;;;;;;;;:15;-1:-1:-1;;;;;82881:15:0;;;-1:-1:-1;;;;;82881:15:0;;;;;82849:55;82935:3;82912:4;82917:14;82930:1;82917:10;:14;:::i;:::-;82912:20;;;;;;-1:-1:-1;;;82912:20:0;;;;;;;;;;;;;;:26;-1:-1:-1;;;;;82912:26:0;;;-1:-1:-1;;;;;82912:26:0;;;;;82955:4;82975:10;-1:-1:-1;;;;;82961:25:0;;;;;-1:-1:-1;;;82961:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82961:25:0;;82947:40;;;;;;82557:436;;;;;;:::o;77579:408::-;77818:163;77832:7;77848:13;77870;77892;77914:14;77937;77960;77818:163;;;;;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;:::o;14:311:1:-;;120:54;136:37;166:6;136:37;:::i;:::-;120:54;:::i;:::-;111:63;;197:6;190:5;183:21;237:3;228:6;223:3;219:16;216:25;213:2;;;254:1;251;244:12;213:2;267:52;312:6;305:4;298:5;294:16;289:3;267:52;:::i;330:151::-;406:20;;455:1;445:12;;435:2;;471:1;468;461:12;486:148;559:20;;608:1;598:12;;588:2;;624:1;621;614:12;639:181;708:20;;-1:-1:-1;;;;;757:38:1;;747:49;;737:2;;810:1;807;800:12;825:259;;937:2;925:9;916:7;912:23;908:32;905:2;;;958:6;950;943:22;905:2;1002:9;989:23;1021:33;1048:5;1021:33;:::i;1089:271::-;;1220:2;1208:9;1199:7;1195:23;1191:32;1188:2;;;1241:6;1233;1226:22;1188:2;1278:9;1272:16;1297:33;1324:5;1297:33;:::i;1365:478::-;;;;1519:2;1507:9;1498:7;1494:23;1490:32;1487:2;;;1540:6;1532;1525:22;1487:2;1584:9;1571:23;1603:33;1630:5;1603:33;:::i;:::-;1655:5;-1:-1:-1;1712:2:1;1697:18;;1684:32;1725:35;1684:32;1725:35;:::i;:::-;1477:366;;1779:7;;-1:-1:-1;;;1833:2:1;1818:18;;;;1805:32;;1477:366::o;1848:335::-;;;1985:2;1973:9;1964:7;1960:23;1956:32;1953:2;;;2006:6;1998;1991:22;1953:2;2050:9;2037:23;2069:33;2096:5;2069:33;:::i;:::-;2121:5;2173:2;2158:18;;;;2145:32;;-1:-1:-1;;;1943:240:1:o;2188:854::-;;;;;2361:2;2349:9;2340:7;2336:23;2332:32;2329:2;;;2382:6;2374;2367:22;2329:2;2426:9;2413:23;2445:33;2472:5;2445:33;:::i;:::-;2497:5;-1:-1:-1;2549:2:1;2534:18;;2521:32;;-1:-1:-1;2604:2:1;2589:18;;2576:32;-1:-1:-1;;;;;2657:14:1;;;2654:2;;;2689:6;2681;2674:22;2654:2;2732:6;2721:9;2717:22;2707:32;;2777:7;2770:4;2766:2;2762:13;2758:27;2748:2;;2804:6;2796;2789:22;2748:2;2849;2836:16;2875:2;2867:6;2864:14;2861:2;;;2896:6;2888;2881:22;2861:2;2946:7;2941:2;2932:6;2928:2;2924:15;2920:24;2917:37;2914:2;;;2972:6;2964;2957:22;2914:2;2319:723;;;;-1:-1:-1;;3008:2:1;3000:11;;-1:-1:-1;;;2319:723:1:o;3047:402::-;;;3176:2;3164:9;3155:7;3151:23;3147:32;3144:2;;;3197:6;3189;3182:22;3144:2;3241:9;3228:23;3260:33;3287:5;3260:33;:::i;:::-;3312:5;-1:-1:-1;3369:2:1;3354:18;;3341:32;3382:35;3341:32;3382:35;:::i;:::-;3436:7;3426:17;;;3134:315;;;;;:::o;3454:636::-;;;;;3639:3;3627:9;3618:7;3614:23;3610:33;3607:2;;;3661:6;3653;3646:22;3607:2;3705:9;3692:23;3724:33;3751:5;3724:33;:::i;:::-;3776:5;-1:-1:-1;3833:2:1;3818:18;;3805:32;3846:35;3805:32;3846:35;:::i;:::-;3900:7;-1:-1:-1;3959:2:1;3944:18;;3931:32;3972:35;3931:32;3972:35;:::i;:::-;3597:493;;;;-1:-1:-1;4026:7:1;;4080:2;4065:18;4052:32;;-1:-1:-1;;3597:493:1:o;4095:464::-;;;;;4258:3;4246:9;4237:7;4233:23;4229:33;4226:2;;;4280:6;4272;4265:22;4226:2;4324:9;4311:23;4343:33;4370:5;4343:33;:::i;:::-;4395:5;4447:2;4432:18;;4419:32;;-1:-1:-1;4498:2:1;4483:18;;4470:32;;4549:2;4534:18;4521:32;;-1:-1:-1;4216:343:1;-1:-1:-1;;;4216:343:1:o;4564:558::-;;;;;;4755:3;4743:9;4734:7;4730:23;4726:33;4723:2;;;4777:6;4769;4762:22;4723:2;4821:9;4808:23;4840:33;4867:5;4840:33;:::i;:::-;4892:5;-1:-1:-1;4944:2:1;4929:18;;4916:32;;-1:-1:-1;4995:2:1;4980:18;;4967:32;;-1:-1:-1;5046:2:1;5031:18;;5018:32;;-1:-1:-1;5069:47:1;5111:3;5096:19;;5069:47;:::i;:::-;5059:57;;4713:409;;;;;;;;:::o;5127:533::-;;;;;;5307:3;5295:9;5286:7;5282:23;5278:33;5275:2;;;5329:6;5321;5314:22;5275:2;5373:9;5360:23;5392:33;5419:5;5392:33;:::i;:::-;5444:5;5496:2;5481:18;;5468:32;;-1:-1:-1;5547:2:1;5532:18;;5519:32;;5598:2;5583:18;;5570:32;;-1:-1:-1;5649:3:1;5634:19;5621:33;;-1:-1:-1;5265:395:1;-1:-1:-1;;;5265:395:1:o;5665:627::-;;;;;;;5873:3;5861:9;5852:7;5848:23;5844:33;5841:2;;;5895:6;5887;5880:22;5841:2;5939:9;5926:23;5958:33;5985:5;5958:33;:::i;:::-;6010:5;-1:-1:-1;6062:2:1;6047:18;;6034:32;;-1:-1:-1;6113:2:1;6098:18;;6085:32;;-1:-1:-1;6164:2:1;6149:18;;6136:32;;-1:-1:-1;6215:3:1;6200:19;;6187:33;;-1:-1:-1;6239:47:1;6281:3;6266:19;;6239:47;:::i;:::-;6229:57;;5831:461;;;;;;;;:::o;6297:696::-;;;;;;;;6522:3;6510:9;6501:7;6497:23;6493:33;6490:2;;;6544:6;6536;6529:22;6490:2;6588:9;6575:23;6607:33;6634:5;6607:33;:::i;:::-;6659:5;-1:-1:-1;6711:2:1;6696:18;;6683:32;;-1:-1:-1;6762:2:1;6747:18;;6734:32;;-1:-1:-1;6813:2:1;6798:18;;6785:32;;-1:-1:-1;6864:3:1;6849:19;;6836:33;;-1:-1:-1;6916:3:1;6901:19;;6888:33;;-1:-1:-1;6940:47:1;6982:3;6967:19;;6940:47;:::i;:::-;6930:57;;6480:513;;;;;;;;;;:::o;6998:1585::-;;7150:2;7193;7181:9;7172:7;7168:23;7164:32;7161:2;;;7214:6;7206;7199:22;7161:2;7252:9;7246:16;-1:-1:-1;;;;;7322:2:1;7314:6;7311:14;7308:2;;;7343:6;7335;7328:22;7308:2;7386:6;7375:9;7371:22;7361:32;;7431:7;7424:4;7420:2;7416:13;7412:27;7402:2;;7458:6;7450;7443:22;7402:2;7492;7486:9;7515:77;7531:60;7588:2;7531:60;:::i;7515:77::-;7626:15;;;7657:12;;;;7689:11;;;7718:6;7733:820;7747:2;7744:1;7741:9;7733:820;;;7816:3;7810:10;7806:2;7802:19;7844:4;7900:2;7894;7890:7;7885:2;7876:7;7872:16;7868:30;7864:39;7861:2;;;7921:6;7913;7906:22;7861:2;7956:19;7972:2;7956:19;:::i;:::-;8017:2;8013;8009:11;8003:18;8034:32;8058:7;8034:32;:::i;:::-;8079:22;;8136:11;;;8130:18;8164:16;;;8161:2;;;8198:6;8190;8183:22;8161:2;8238:8;8234:2;8230:17;8220:27;;;8287:7;8282:2;8278;8274:11;8270:25;8260:2;;8314:6;8306;8299:22;8260:2;8359:88;8439:7;8433:2;8429;8425:11;8419:18;8414:2;8410;8406:11;8359:88;:::i;:::-;8343:14;;;8336:112;8461:18;;-1:-1:-1;;8499:12:1;;;;8531;;;;7765:1;7758:9;7733:820;;;-1:-1:-1;8572:5:1;;7130:1453;-1:-1:-1;;;;;;;;;7130:1453:1:o;8588:687::-;;;8756:2;8744:9;8735:7;8731:23;8727:32;8724:2;;;8777:6;8769;8762:22;8724:2;8822:9;8809:23;-1:-1:-1;;;;;8892:2:1;8884:6;8881:14;8878:2;;;8913:6;8905;8898:22;8878:2;8956:6;8945:9;8941:22;8931:32;;9001:7;8994:4;8990:2;8986:13;8982:27;8972:2;;9028:6;9020;9013:22;8972:2;9073;9060:16;9099:2;9091:6;9088:14;9085:2;;;9120:6;9112;9105:22;9085:2;9179:7;9174:2;9168;9160:6;9156:15;9152:2;9148:24;9144:33;9141:46;9138:2;;;9205:6;9197;9190:22;9138:2;9241;9233:11;;;;;9263:6;;-1:-1:-1;8714:561:1;;-1:-1:-1;;;;8714:561:1:o;9280:1956::-;;9414:2;9457;9445:9;9436:7;9432:23;9428:32;9425:2;;;9478:6;9470;9463:22;9425:2;9523:9;9510:23;-1:-1:-1;;;;;9593:2:1;9585:6;9582:14;9579:2;;;9614:6;9606;9599:22;9579:2;9657:6;9646:9;9642:22;9632:32;;9702:7;9695:4;9691:2;9687:13;9683:27;9673:2;;9729:6;9721;9714:22;9673:2;9770;9757:16;9793:77;9809:60;9866:2;9809:60;:::i;9793:77::-;9904:15;;;9935:12;;;;9967:11;;;9996:6;10011:1195;10025:2;10022:1;10019:9;10011:1195;;;10101:3;10088:17;10084:2;10080:26;10129:4;10185:2;10179;10175:7;10170:2;10161:7;10157:16;10153:30;10149:39;10146:2;;;10206:6;10198;10191:22;10146:2;10241:19;10257:2;10241:19;:::i;:::-;10309:2;10305;10301:11;10288:25;10326:35;10353:7;10326:35;:::i;:::-;10374:22;;10419:2;10457:32;10477:11;;;10457:32;:::i;:::-;10441:14;;;10434:56;10532:11;;;10519:25;;10560:16;;;10557:2;;;10594:6;10586;10579:22;10557:2;10634:8;10630:2;10626:17;10616:27;;10683:7;10678:2;10674;10670:11;10666:25;10656:2;;10710:6;10702;10695:22;10656:2;10763;10759;10755:11;10742:25;10732:35;;10793:50;10809:33;10839:2;10809:33;:::i;10793:50::-;10870:2;10863:5;10856:17;10914:7;10909:2;10904;10900;10896:11;10892:20;10889:33;10886:2;;;10940:6;10932;10925:22;10886:2;11004;10999;10995;10991:11;10986:2;10979:5;10975:14;10962:45;11031:14;;;11027:23;;11020:39;;;11079:14;;11072:29;;;;11114:18;;-1:-1:-1;11152:12:1;;;;11184;;;;10043:1;10036:9;10011:1195;;11241:955;;11367:2;11410;11398:9;11389:7;11385:23;11381:32;11378:2;;;11431:6;11423;11416:22;11378:2;11469:9;11463:16;-1:-1:-1;;;;;11494:6:1;11491:30;11488:2;;;11539:6;11531;11524:22;11488:2;11567:22;;11620:4;11612:13;;11608:27;-1:-1:-1;11598:2:1;;11654:6;11646;11639:22;11598:2;11688;11682:9;11711:77;11727:60;11784:2;11727:60;:::i;11711:77::-;11822:15;;;11853:12;;;;11885:11;;;11923;;;11915:20;;11911:29;;11908:42;-1:-1:-1;11905:2:1;;;11968:6;11960;11953:22;11905:2;11995:6;11986:15;;12010:156;12024:2;12021:1;12018:9;12010:156;;;12081:10;;12069:23;;12042:1;12035:9;;;;;12112:12;;;;12144;;12010:156;;;-1:-1:-1;12185:5:1;11347:849;-1:-1:-1;;;;;;;11347:849:1:o;12201:257::-;;12321:2;12309:9;12300:7;12296:23;12292:32;12289:2;;;12342:6;12334;12327:22;12289:2;12379:9;12373:16;12398:30;12422:5;12398:30;:::i;12463:492::-;;;;12631:2;12619:9;12610:7;12606:23;12602:32;12599:2;;;12652:6;12644;12637:22;12960:837;;;;;;;;13193:3;13181:9;13172:7;13168:23;13164:33;13161:2;;;13215:6;13207;13200:22;13161:2;13259:9;13246:23;13278:33;13305:5;13278:33;:::i;:::-;13330:5;-1:-1:-1;13387:2:1;13372:18;;13359:32;13400:35;13359:32;13400:35;:::i;:::-;13454:7;-1:-1:-1;13508:2:1;13493:18;;13480:32;;-1:-1:-1;13559:2:1;13544:18;;13531:32;;-1:-1:-1;13610:3:1;13595:19;;13582:33;;-1:-1:-1;13662:3:1;13647:19;;13634:33;;-1:-1:-1;13719:3:1;13704:19;;13691:33;13733:32;13691:33;13733:32;:::i;:::-;13784:7;13774:17;;;13151:646;;;;;;;;;;:::o;13802:931::-;;;;;;;;;14063:3;14051:9;14042:7;14038:23;14034:33;14031:2;;;14085:6;14077;14070:22;14031:2;14129:9;14116:23;14148:33;14175:5;14148:33;:::i;:::-;14200:5;-1:-1:-1;14257:2:1;14242:18;;14229:32;14270:35;14229:32;14270:35;:::i;:::-;14324:7;-1:-1:-1;14378:2:1;14363:18;;14350:32;;-1:-1:-1;14429:2:1;14414:18;;14401:32;;-1:-1:-1;14480:3:1;14465:19;;14452:33;;-1:-1:-1;14532:3:1;14517:19;;14504:33;;-1:-1:-1;14589:3:1;14574:19;;14561:33;14603:32;14561:33;14603:32;:::i;:::-;14654:7;-1:-1:-1;14680:47:1;14722:3;14707:19;;14680:47;:::i;:::-;14670:57;;14021:712;;;;;;;;;;;:::o;14738:1000::-;;;;;;;;;;15016:3;15004:9;14995:7;14991:23;14987:33;14984:2;;;15038:6;15030;15023:22;14984:2;15082:9;15069:23;15101:33;15128:5;15101:33;:::i;:::-;15153:5;-1:-1:-1;15210:2:1;15195:18;;15182:32;15223:35;15182:32;15223:35;:::i;:::-;15277:7;-1:-1:-1;15331:2:1;15316:18;;15303:32;;-1:-1:-1;15382:2:1;15367:18;;15354:32;;-1:-1:-1;15433:3:1;15418:19;;15405:33;;-1:-1:-1;15485:3:1;15470:19;;15457:33;;-1:-1:-1;15537:3:1;15522:19;;15509:33;;-1:-1:-1;15594:3:1;15579:19;;15566:33;15608:32;15566:33;15608:32;:::i;:::-;15659:7;-1:-1:-1;15685:47:1;15727:3;15712:19;;15685:47;:::i;:::-;15675:57;;14974:764;;;;;;;;;;;:::o;16888:209::-;;17008:2;16996:9;16987:7;16983:23;16979:32;16976:2;;;17029:6;17021;17014:22;16976:2;17057:34;17081:9;17057:34;:::i;17102:346::-;;;17239:2;17227:9;17218:7;17214:23;17210:32;17207:2;;;17260:6;17252;17245:22;17207:2;17288:34;17312:9;17288:34;:::i;17453:490::-;;17586:2;17574:9;17565:7;17561:23;17557:32;17554:2;;;17607:6;17599;17592:22;17554:2;17645:9;17639:16;-1:-1:-1;;;;;17670:6:1;17667:30;17664:2;;;17715:6;17707;17700:22;17664:2;17743:22;;17796:4;17788:13;;17784:27;-1:-1:-1;17774:2:1;;17830:6;17822;17815:22;17774:2;17858:79;17929:7;17924:2;17918:9;17913:2;17909;17905:11;17858:79;:::i;17948:190::-;;18060:2;18048:9;18039:7;18035:23;18031:32;18028:2;;;18081:6;18073;18066:22;18028:2;-1:-1:-1;18109:23:1;;18018:120;-1:-1:-1;18018:120:1:o;18143:194::-;;18266:2;18254:9;18245:7;18241:23;18237:32;18234:2;;;18287:6;18279;18272:22;18234:2;-1:-1:-1;18315:16:1;;18224:113;-1:-1:-1;18224:113:1:o;18342:469::-;;18439:5;18433:12;18466:6;18461:3;18454:19;18492:4;18521:2;18516:3;18512:12;18505:19;;18558:2;18551:5;18547:14;18579:3;18591:195;18605:6;18602:1;18599:13;18591:195;;;18670:13;;-1:-1:-1;;;;;18666:39:1;18654:52;;18726:12;;;;18761:15;;;;18702:1;18620:9;18591:195;;;-1:-1:-1;18802:3:1;;18409:402;-1:-1:-1;;;;;18409:402:1:o;18816:456::-;;18910:5;18904:12;18937:6;18932:3;18925:19;18963:4;18992:2;18987:3;18983:12;18976:19;;19029:2;19022:5;19018:14;19050:3;19062:185;19076:6;19073:1;19070:13;19062:185;;;19151:13;;19144:21;19137:29;19125:42;;19187:12;;;;19222:15;;;;19098:1;19091:9;19062:185;;19277:625;;19372:5;19366:12;19399:6;19394:3;19387:19;19425:4;19466:2;19461:3;19457:12;19491:11;19518;19511:18;;19573:2;19565:6;19561:15;19554:5;19550:27;19538:39;;19611:2;19604:5;19600:14;19632:3;19644:232;19658:6;19655:1;19652:13;19644:232;;;19729:5;19723:4;19719:16;19714:3;19707:29;19757:39;19791:4;19782:6;19776:13;19757:39;:::i;:::-;19854:12;;;;19749:47;-1:-1:-1;19819:15:1;;;;19680:1;19673:9;19644:232;;;-1:-1:-1;19892:4:1;;19342:560;-1:-1:-1;;;;;;;19342:560:1:o;19907:270::-;;19997:6;19992:3;19985:19;20049:6;20042:5;20035:4;20030:3;20026:14;20013:43;20101:3;20094:4;20085:6;20080:3;20076:16;20072:27;20065:40;20166:4;20159:2;20155:7;20150:2;20142:6;20138:15;20134:29;20129:3;20125:39;20121:50;20114:57;;19975:202;;;;;:::o;20182:259::-;;20263:5;20257:12;20290:6;20285:3;20278:19;20306:63;20362:6;20355:4;20350:3;20346:14;20339:4;20332:5;20328:16;20306:63;:::i;:::-;20423:2;20402:15;-1:-1:-1;;20398:29:1;20389:39;;;;20430:4;20385:50;;20233:208;-1:-1:-1;;20233:208:1:o;20446:348::-;-1:-1:-1;;20643:42:1;;;;20631:55;;20711:2;20702:12;;20695:28;;;;20748:2;20739:12;;20732:28;20785:2;20776:12;;20621:173::o;20799:273::-;;20982:6;20974;20969:3;20956:33;21008:16;;21033:15;;;21008:16;20946:126;-1:-1:-1;20946:126:1:o;21077:274::-;;21244:6;21238:13;21260:53;21306:6;21301:3;21294:4;21286:6;21282:17;21260:53;:::i;:::-;21329:16;;;;;21214:137;-1:-1:-1;;21214:137:1:o;21356:504::-;;21579:6;21573:13;21595:53;21641:6;21636:3;21629:4;21621:6;21617:17;21595:53;:::i;:::-;21717:2;21713:15;;;;-1:-1:-1;;21709:53:1;21670:16;;;;21695:68;;;-1:-1:-1;;21795:28:1;;;;21790:2;21779:14;;21772:52;21851:2;21840:14;;21549:311;-1:-1:-1;;21549:311:1:o;21865:205::-;22065:3;22056:14::o;22075:203::-;-1:-1:-1;;;;;22239:32:1;;;;22221:51;;22209:2;22194:18;;22176:102::o;22283:304::-;-1:-1:-1;;;;;22513:15:1;;;22495:34;;22565:15;;22560:2;22545:18;;22538:43;22445:2;22430:18;;22412:175::o;22592:681::-;-1:-1:-1;;;;;22963:15:1;;;22945:34;;23015:15;;;23010:2;22995:18;;22988:43;23067:15;;;23062:2;23047:18;;23040:43;23119:15;;;;23114:2;23099:18;;23092:43;23166:3;23151:19;;23144:35;;;;22925:3;23195:19;;23188:35;;;;23254:3;23239:19;;23232:35;;;;22894:3;22879:19;;22861:412::o;23278:375::-;-1:-1:-1;;;;;23536:15:1;;;23518:34;;23588:15;;;;23583:2;23568:18;;23561:43;23635:2;23620:18;;23613:34;;;;23468:2;23453:18;;23435:218::o;23658:274::-;-1:-1:-1;;;;;23850:32:1;;;;23832:51;;23914:2;23899:18;;23892:34;23820:2;23805:18;;23787:145::o;23937:553::-;;24217:1;24213;24208:3;24204:11;24200:19;24192:6;24188:32;24177:9;24170:51;24257:6;24252:2;24241:9;24237:18;24230:34;24300:3;24295:2;24284:9;24280:18;24273:31;24327:47;24369:3;24358:9;24354:19;24346:6;24327:47;:::i;:::-;24422:9;24414:6;24410:22;24405:2;24394:9;24390:18;24383:50;24450:34;24477:6;24469;24450:34;:::i;24495:484::-;;24764:2;24753:9;24746:21;24790:59;24845:2;24834:9;24830:18;24822:6;24790:59;:::i;:::-;24897:9;24889:6;24885:22;24880:2;24869:9;24865:18;24858:50;24925:48;24966:6;24958;24925:48;:::i;24984:565::-;;25275:2;25264:9;25257:21;25301:59;25356:2;25345:9;25341:18;25333:6;25301:59;:::i;:::-;25408:9;25400:6;25396:22;25391:2;25380:9;25376:18;25369:50;25436:48;25477:6;25469;25436:48;:::i;:::-;25428:56;;;25534:6;25527:14;25520:22;25515:2;25504:9;25500:18;25493:50;25247:302;;;;;;:::o;25554:1050::-;25777:2;25829:21;;;25899:13;;25802:18;;;25921:22;;;25554:1050;;25777:2;25962;;25980:18;;;;26040:15;;;26025:31;;26021:40;;26084:15;;;25554:1050;26130:445;26144:6;26141:1;26138:13;26130:445;;;26209:22;;;-1:-1:-1;;26205:36:1;26193:49;;26265:13;;26320:9;;26313:17;26306:25;26291:41;;26371:11;;26365:18;26403:15;;;26396:27;;;26446:49;26479:15;;;26365:18;26446:49;:::i;:::-;26553:12;;;;26436:59;-1:-1:-1;;26518:15:1;;;;26166:1;26159:9;26130:445;;;-1:-1:-1;26592:6:1;;25757:847;-1:-1:-1;;;;;;;;25757:847:1:o;26609:1840::-;26830:2;26882:21;;;26855:18;;;26938:22;;;26609:1840;;26979:2;26997:18;;;27057:15;;;27042:31;;27038:40;;27101:6;26609:1840;27138:1282;27152:6;27149:1;27146:13;27138:1282;;;27217:22;;;-1:-1:-1;;27213:36:1;27201:49;;27289:20;;27364:14;27360:27;;;-1:-1:-1;;27356:41:1;27332:66;;27322:2;;27415:4;27409;27402:18;27322:2;27448:31;;27502:4;27534:19;;27566:35;27534:19;27566:35;:::i;:::-;-1:-1:-1;;;;;27629:33:1;27614:49;;-1:-1:-1;;;;;27704:35:1;27724:14;;;27704:35;:::i;:::-;27700:68;27695:2;27687:6;27683:15;27676:93;27834:2;27827:5;27823:14;27810:28;27923:2;27919:7;27911:5;27895:14;27891:26;27887:40;27865:20;27861:67;27851:2;;27945:4;27939;27932:18;27851:2;27980:32;;28039:21;;-1:-1:-1;;;;;28076:30:1;;28073:2;;;28122:4;28116;28109:18;28073:2;28176:6;28160:14;28156:27;28149:5;28145:39;28142:2;;;28200:4;28194;28187:18;28142:2;28244;28239;28231:6;28227:15;28220:27;28270:70;28336:2;28328:6;28324:15;28316:6;28311:2;28302:7;28298:16;28270:70;:::i;:::-;28398:12;;;;28260:80;-1:-1:-1;;;28363:15:1;;;;-1:-1:-1;;27174:1:1;27167:9;27138:1282;;28454:1162;28663:2;28715:21;;;28785:13;;28688:18;;;28807:22;;;28454:1162;;28663:2;28848;;28866:18;;;;28926:15;;;28911:31;;28907:40;;28970:15;;;28454:1162;29016:571;29030:6;29027:1;29024:13;29016:571;;;29095:22;;;-1:-1:-1;;29091:36:1;29079:49;;29151:13;;29223:9;;-1:-1:-1;;;;;29219:35:1;29204:51;;29302:11;;;29296:18;-1:-1:-1;;;;;29292:51:1;29275:15;;;29268:76;29383:11;;29377:18;29187:4;29415:15;;;29408:27;;;29458:49;29491:15;;;29377:18;29458:49;:::i;:::-;29565:12;;;;29448:59;-1:-1:-1;;;29530:15:1;;;;29052:1;29045:9;29016:571;;29621:187;29786:14;;29779:22;29761:41;;29749:2;29734:18;;29716:92::o;29813:633::-;;30098:6;30091:14;30084:22;30073:9;30066:41;30172:1;30168;30163:3;30159:11;30155:19;30147:6;30143:32;30138:2;30127:9;30123:18;30116:60;30212:6;30207:2;30196:9;30192:18;30185:34;30255:3;30250:2;30239:9;30235:18;30228:31;30282:47;30324:3;30313:9;30309:19;30301:6;30282:47;:::i;:::-;30378:9;30370:6;30366:22;30360:3;30349:9;30345:19;30338:51;30406:34;30433:6;30425;30406:34;:::i;30451:300::-;;30634:6;30627:14;30620:22;30609:9;30602:41;30679:2;30674;30663:9;30659:18;30652:30;30699:46;30741:2;30730:9;30726:18;30718:6;30699:46;:::i;30986:422::-;31188:2;31170:21;;;31227:2;31207:18;;;31200:30;31266:34;31261:2;31246:18;;31239:62;31337:28;31332:2;31317:18;;31310:56;31398:3;31383:19;;31160:248::o;31413:346::-;31615:2;31597:21;;;31654:2;31634:18;;;31627:30;-1:-1:-1;;;31688:2:1;31673:18;;31666:52;31750:2;31735:18;;31587:172::o;31764:343::-;31966:2;31948:21;;;32005:2;31985:18;;;31978:30;-1:-1:-1;;;32039:2:1;32024:18;;32017:49;32098:2;32083:18;;31938:169::o;32112:472::-;32314:2;32296:21;;;32353:2;32333:18;;;32326:30;32392:34;32387:2;32372:18;;32365:62;32463:34;32458:2;32443:18;;32436:62;-1:-1:-1;;;32529:3:1;32514:19;;32507:35;32574:3;32559:19;;32286:298::o;32589:426::-;32791:2;32773:21;;;32830:2;32810:18;;;32803:30;32869:34;32864:2;32849:18;;32842:62;32940:32;32935:2;32920:18;;32913:60;33005:3;32990:19;;32763:252::o;33020:473::-;33222:2;33204:21;;;33261:2;33241:18;;;33234:30;33300:34;33295:2;33280:18;;33273:62;33371:34;33366:2;33351:18;;33344:62;-1:-1:-1;;;33437:3:1;33422:19;;33415:36;33483:3;33468:19;;33194:299::o;33498:401::-;33700:2;33682:21;;;33739:2;33719:18;;;33712:30;33778:34;33773:2;33758:18;;33751:62;-1:-1:-1;;;33844:2:1;33829:18;;33822:35;33889:3;33874:19;;33672:227::o;33904:347::-;34106:2;34088:21;;;34145:2;34125:18;;;34118:30;34184:25;34179:2;34164:18;;34157:53;34242:2;34227:18;;34078:173::o;34256:473::-;34458:2;34440:21;;;34497:2;34477:18;;;34470:30;34536:34;34531:2;34516:18;;34509:62;34607:34;34602:2;34587:18;;34580:62;-1:-1:-1;;;34673:3:1;34658:19;;34651:36;34719:3;34704:19;;34430:299::o;34734:404::-;34936:2;34918:21;;;34975:2;34955:18;;;34948:30;35014:34;35009:2;34994:18;;34987:62;-1:-1:-1;;;35080:2:1;35065:18;;35058:38;35128:3;35113:19;;34908:230::o;35143:347::-;35345:2;35327:21;;;35384:2;35364:18;;;35357:30;35423:25;35418:2;35403:18;;35396:53;35481:2;35466:18;;35317:173::o;35495:344::-;35697:2;35679:21;;;35736:2;35716:18;;;35709:30;-1:-1:-1;;;35770:2:1;35755:18;;35748:50;35830:2;35815:18;;35669:170::o;35844:405::-;36046:2;36028:21;;;36085:2;36065:18;;;36058:30;36124:34;36119:2;36104:18;;36097:62;-1:-1:-1;;;36190:2:1;36175:18;;36168:39;36239:3;36224:19;;36018:231::o;36254:403::-;36456:2;36438:21;;;36495:2;36475:18;;;36468:30;36534:34;36529:2;36514:18;;36507:62;-1:-1:-1;;;36600:2:1;36585:18;;36578:37;36647:3;36632:19;;36428:229::o;36662:401::-;36864:2;36846:21;;;36903:2;36883:18;;;36876:30;36942:34;36937:2;36922:18;;36915:62;-1:-1:-1;;;37008:2:1;36993:18;;36986:35;37053:3;37038:19;;36836:227::o;37068:401::-;37270:2;37252:21;;;37309:2;37289:18;;;37282:30;37348:34;37343:2;37328:18;;37321:62;-1:-1:-1;;;37414:2:1;37399:18;;37392:35;37459:3;37444:19;;37242:227::o;37474:399::-;37676:2;37658:21;;;37715:2;37695:18;;;37688:30;37754:34;37749:2;37734:18;;37727:62;-1:-1:-1;;;37820:2:1;37805:18;;37798:33;37863:3;37848:19;;37648:225::o;37878:472::-;38080:2;38062:21;;;38119:2;38099:18;;;38092:30;38158:34;38153:2;38138:18;;38131:62;38229:34;38224:2;38209:18;;38202:62;-1:-1:-1;;;38295:3:1;38280:19;;38273:35;38340:3;38325:19;;38052:298::o;38355:404::-;38557:2;38539:21;;;38596:2;38576:18;;;38569:30;38635:34;38630:2;38615:18;;38608:62;-1:-1:-1;;;38701:2:1;38686:18;;38679:38;38749:3;38734:19;;38529:230::o;38764:420::-;38966:2;38948:21;;;39005:2;38985:18;;;38978:30;39044:34;39039:2;39024:18;;39017:62;39115:26;39110:2;39095:18;;39088:54;39174:3;39159:19;;38938:246::o;39189:177::-;39335:25;;;39323:2;39308:18;;39290:76::o;39371:508::-;;39634:6;39623:9;39616:25;39677:3;39672:2;39661:9;39657:18;39650:31;39698:63;39756:3;39745:9;39741:19;39733:6;39698:63;:::i;:::-;-1:-1:-1;;;;;39797:32:1;;;;39792:2;39777:18;;39770:60;-1:-1:-1;39861:2:1;39846:18;39839:34;39690:71;39606:273;-1:-1:-1;;39606:273:1:o;39884:580::-;;40175:6;40164:9;40157:25;40218:6;40213:2;40202:9;40198:18;40191:34;40261:3;40256:2;40245:9;40241:18;40234:31;40282:63;40340:3;40329:9;40325:19;40317:6;40282:63;:::i;:::-;-1:-1:-1;;;;;40381:32:1;;;;40376:2;40361:18;;40354:60;-1:-1:-1;40445:3:1;40430:19;40423:35;40274:71;40147:317;-1:-1:-1;;;40147:317:1:o;40469:275::-;40540:2;40534:9;40605:2;40586:13;;-1:-1:-1;;40582:27:1;40570:40;;-1:-1:-1;;;;;40625:34:1;;40661:22;;;40622:62;40619:2;;;40687:18;;:::i;:::-;40723:2;40716:22;40514:230;;-1:-1:-1;40514:230:1:o;40749:203::-;;-1:-1:-1;;;;;40851:6:1;40848:30;40845:2;;;40881:18;;:::i;:::-;-1:-1:-1;40941:4:1;40922:17;;;40918:28;;40835:117::o;40957:188::-;;-1:-1:-1;;;;;41032:6:1;41029:30;41026:2;;;41062:18;;:::i;:::-;-1:-1:-1;41128:2:1;41107:15;-1:-1:-1;;41103:29:1;41134:4;41099:40;;41016:129::o;41150:128::-;;41221:1;41217:6;41214:1;41211:13;41208:2;;;41227:18;;:::i;:::-;-1:-1:-1;41263:9:1;;41198:80::o;41283:125::-;;41351:1;41348;41345:8;41342:2;;;41356:18;;:::i;:::-;-1:-1:-1;41393:9:1;;41332:76::o;41413:258::-;41485:1;41495:113;41509:6;41506:1;41503:13;41495:113;;;41585:11;;;41579:18;41566:11;;;41559:39;41531:2;41524:10;41495:113;;;41626:6;41623:1;41620:13;41617:2;;;-1:-1:-1;;41661:1:1;41643:16;;41636:27;41466:205::o;41676:135::-;;-1:-1:-1;;41736:17:1;;41733:2;;;41756:18;;:::i;:::-;-1:-1:-1;41803:1:1;41792:13;;41723:88::o;41816:127::-;41877:10;41872:3;41868:20;41865:1;41858:31;41908:4;41905:1;41898:15;41932:4;41929:1;41922:15;41948:127;42009:10;42004:3;42000:20;41997:1;41990:31;42040:4;42037:1;42030:15;42064:4;42061:1;42054:15;42080:133;-1:-1:-1;;;;;42157:31:1;;42147:42;;42137:2;;42203:1;42200;42193:12;42218:120;42306:5;42299:13;42292:21;42285:5;42282:32;42272:2;;42328:1;42325;42318:12
Swarm Source
ipfs://784b1cc3f6622b5c7aae2f03aa8870aed35115d5feb5040157029b0dff2d8f23
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.