Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 173 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Manage Vault Wit... | 23510237 | 2 days ago | IN | 0 ETH | 0.00027377 | ||||
Manage Vault Wit... | 23510236 | 2 days ago | IN | 0 ETH | 0.00010647 | ||||
Manage Vault Wit... | 23510235 | 2 days ago | IN | 0 ETH | 0.00014463 | ||||
Manage Vault Wit... | 23510234 | 2 days ago | IN | 0 ETH | 0.00009771 | ||||
Manage Vault Wit... | 23510233 | 2 days ago | IN | 0 ETH | 0.00011665 | ||||
Manage Vault Wit... | 23510232 | 2 days ago | IN | 0 ETH | 0.0001049 | ||||
Manage Vault Wit... | 23503438 | 3 days ago | IN | 0 ETH | 0.00004976 | ||||
Manage Vault Wit... | 23498684 | 4 days ago | IN | 0 ETH | 0.00097437 | ||||
Manage Vault Wit... | 23482236 | 6 days ago | IN | 0 ETH | 0.00074652 | ||||
Manage Vault Wit... | 23482234 | 6 days ago | IN | 0 ETH | 0.00032064 | ||||
Manage Vault Wit... | 23461367 | 9 days ago | IN | 0 ETH | 0.00005882 | ||||
Manage Vault Wit... | 23461364 | 9 days ago | IN | 0 ETH | 0.00009283 | ||||
Manage Vault Wit... | 23461363 | 9 days ago | IN | 0 ETH | 0.0000692 | ||||
Manage Vault Wit... | 23461362 | 9 days ago | IN | 0 ETH | 0.0000727 | ||||
Manage Vault Wit... | 23461361 | 9 days ago | IN | 0 ETH | 0.00007891 | ||||
Manage Vault Wit... | 23461360 | 9 days ago | IN | 0 ETH | 0.00007055 | ||||
Manage Vault Wit... | 23457782 | 10 days ago | IN | 0 ETH | 0.00007243 | ||||
Manage Vault Wit... | 23456592 | 10 days ago | IN | 0 ETH | 0.00006203 | ||||
Manage Vault Wit... | 23456591 | 10 days ago | IN | 0 ETH | 0.00009048 | ||||
Manage Vault Wit... | 23456590 | 10 days ago | IN | 0 ETH | 0.00006749 | ||||
Manage Vault Wit... | 23456589 | 10 days ago | IN | 0 ETH | 0.00006531 | ||||
Manage Vault Wit... | 23448614 | 11 days ago | IN | 0 ETH | 0.00029579 | ||||
Manage Vault Wit... | 23448243 | 11 days ago | IN | 0 ETH | 0.00051917 | ||||
Manage Vault Wit... | 23448242 | 11 days ago | IN | 0 ETH | 0.00082091 | ||||
Manage Vault Wit... | 23448241 | 11 days ago | IN | 0 ETH | 0.00054399 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ManagerWithMerkleVerification
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2025-08-31 */ /** *Submitted for verification at Etherscan.io on 2025-07-22 */ // File: lib/solmate/src/utils/FixedPointMathLib.sol pragma solidity >=0.8.0; /// @notice Arithmetic library with operations for fixed-point numbers. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) /// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ uint256 internal constant MAX_UINT256 = 2**256 - 1; uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } /*////////////////////////////////////////////////////////////// LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // Divide x * y by the denominator. z := div(mul(x, y), denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // If x * y modulo the denominator is strictly greater than 0, // 1 is added to round up the division of x * y by the denominator. z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator)) } } function rpow( uint256 x, uint256 n, uint256 scalar ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { switch x case 0 { switch n case 0 { // 0 ** 0 = 1 z := scalar } default { // 0 ** n = 0 z := 0 } } default { switch mod(n, 2) case 0 { // If n is even, store scalar in z for now. z := scalar } default { // If n is odd, store x in z for now. z := x } // Shifting right by 1 is like dividing by 2. let half := shr(1, scalar) for { // Shift n right by 1 before looping to halve it. n := shr(1, n) } n { // Shift n right by 1 each iteration to halve it. n := shr(1, n) } { // Revert immediately if x ** 2 would overflow. // Equivalent to iszero(eq(div(xx, x), x)) here. if shr(128, x) { revert(0, 0) } // Store x squared. let xx := mul(x, x) // Round to the nearest number. let xxRound := add(xx, half) // Revert if xx + half overflowed. if lt(xxRound, xx) { revert(0, 0) } // Set x to scaled xxRound. x := div(xxRound, scalar) // If n is even: if mod(n, 2) { // Compute z * x. let zx := mul(z, x) // If z * x overflowed: if iszero(eq(div(zx, x), z)) { // Revert if x is non-zero. if iszero(iszero(x)) { revert(0, 0) } } // Round to the nearest number. let zxRound := add(zx, half) // Revert if zx + half overflowed. if lt(zxRound, zx) { revert(0, 0) } // Return properly scaled zxRound. z := div(zxRound, scalar) } } } } } /*////////////////////////////////////////////////////////////// GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. // We check y >= 2^(k + 8) but shift right by k bits // each branch to ensure that if x >= 256, then y >= 256. if iszero(lt(y, 0x10000000000000000000000000000000000)) { y := shr(128, y) z := shl(64, z) } if iszero(lt(y, 0x1000000000000000000)) { y := shr(64, y) z := shl(32, z) } if iszero(lt(y, 0x10000000000)) { y := shr(32, y) z := shl(16, z) } if iszero(lt(y, 0x1000000)) { y := shr(16, y) z := shl(8, z) } // Goal was to get z*z*y within a small factor of x. More iterations could // get y in a tighter range. Currently, we will have y in [256, 256*2^16). // We ensured y >= 256 so that the relative difference between y and y+1 is small. // That's not possible if x < 256 but we can just verify those cases exhaustively. // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. // There is no overflow risk here since y < 2^136 after the first branch above. z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) // If x+1 is a perfect square, the Babylonian method cycles between // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. // If you don't care whether the floor or ceil square root is returned, you can remove this statement. z := sub(z, lt(div(x, z), z)) } } function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Mod x by y. Note this will return // 0 instead of reverting if y is zero. z := mod(x, y) } } function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Divide x by y. Note this will return // 0 instead of reverting if y is zero. r := div(x, y) } } function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Add 1 to x * y if x % y > 0. Note this will // return 0 instead of reverting if y is zero. z := add(gt(mod(x, y), 0), div(x, y)) } } } // File: lib/openzeppelin-contracts/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } } // File: lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: lib/openzeppelin-contracts/contracts/token/ERC721/utils/ERC721Holder.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or * {IERC721-setApprovalForAll}. */ abstract contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) { return this.onERC721Received.selector; } } // File: lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.20; /** * @dev Interface that must be implemented by smart contracts in order to receive * ERC-1155 token transfers. */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } // File: lib/openzeppelin-contracts/contracts/token/ERC1155/utils/ERC1155Holder.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.20; /** * @dev Simple implementation of `IERC1155Receiver` that will allow a contract to hold ERC1155 tokens. * * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be * stuck. */ abstract contract ERC1155Holder is ERC165, IERC1155Receiver { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } } // File: lib/solmate/src/tokens/ERC20.sol pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } } // File: lib/solmate/src/utils/SafeTransferLib.sol pragma solidity >=0.8.0; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } } // File: src/interfaces/BeforeTransferHook.sol pragma solidity 0.8.21; interface BeforeTransferHook { function beforeTransfer(address from, address to, address operator) external view; } // File: lib/solmate/src/auth/Auth.sol pragma solidity >=0.8.0; /// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) abstract contract Auth { event OwnershipTransferred(address indexed user, address indexed newOwner); event AuthorityUpdated(address indexed user, Authority indexed newAuthority); address public owner; Authority public authority; constructor(address _owner, Authority _authority) { owner = _owner; authority = _authority; emit OwnershipTransferred(msg.sender, _owner); emit AuthorityUpdated(msg.sender, _authority); } modifier requiresAuth() virtual { require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED"); _; } function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) { Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas. // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be // aware that this makes protected functions uncallable even to the owner if the authority is out of order. return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner; } function setAuthority(Authority newAuthority) public virtual { // We check if the caller is the owner first because we want to ensure they can // always swap out the authority even if it's reverting or using up a lot of gas. require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig)); authority = newAuthority; emit AuthorityUpdated(msg.sender, newAuthority); } function transferOwnership(address newOwner) public virtual requiresAuth { owner = newOwner; emit OwnershipTransferred(msg.sender, newOwner); } } /// @notice A generic interface for a contract which provides authorization data to an Auth instance. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Auth.sol) /// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol) interface Authority { function canCall( address user, address target, bytes4 functionSig ) external view returns (bool); } // File: src/base/BoringVault.sol pragma solidity 0.8.21; contract BoringVault is ERC20, Auth, ERC721Holder, ERC1155Holder { using Address for address; using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; // ========================================= STATE ========================================= /** * @notice Contract responsbile for implementing `beforeTransfer`. */ BeforeTransferHook public hook; //============================== EVENTS =============================== event Enter(address indexed from, address indexed asset, uint256 amount, address indexed to, uint256 shares); event Exit(address indexed to, address indexed asset, uint256 amount, address indexed from, uint256 shares); //============================== CONSTRUCTOR =============================== constructor(address _owner, string memory _name, string memory _symbol, uint8 _decimals) ERC20(_name, _symbol, _decimals) Auth(_owner, Authority(address(0))) {} //============================== MANAGE =============================== /** * @notice Allows manager to make an arbitrary function call from this contract. * @dev Callable by MANAGER_ROLE. */ function manage(address target, bytes calldata data, uint256 value) external requiresAuth returns (bytes memory result) { result = target.functionCallWithValue(data, value); } /** * @notice Allows manager to make arbitrary function calls from this contract. * @dev Callable by MANAGER_ROLE. */ function manage(address[] calldata targets, bytes[] calldata data, uint256[] calldata values) external requiresAuth returns (bytes[] memory results) { uint256 targetsLength = targets.length; results = new bytes[](targetsLength); for (uint256 i; i < targetsLength; ++i) { results[i] = targets[i].functionCallWithValue(data[i], values[i]); } } //============================== ENTER =============================== /** * @notice Allows minter to mint shares, in exchange for assets. * @dev If assetAmount is zero, no assets are transferred in. * @dev Callable by MINTER_ROLE. */ function enter(address from, ERC20 asset, uint256 assetAmount, address to, uint256 shareAmount) external requiresAuth { // Transfer assets in if (assetAmount > 0) asset.safeTransferFrom(from, address(this), assetAmount); // Mint shares. _mint(to, shareAmount); emit Enter(from, address(asset), assetAmount, to, shareAmount); } //============================== EXIT =============================== /** * @notice Allows burner to burn shares, in exchange for assets. * @dev If assetAmount is zero, no assets are transferred out. * @dev Callable by BURNER_ROLE. */ function exit(address to, ERC20 asset, uint256 assetAmount, address from, uint256 shareAmount) external requiresAuth { // Burn shares. _burn(from, shareAmount); // Transfer assets out. if (assetAmount > 0) asset.safeTransfer(to, assetAmount); emit Exit(to, address(asset), assetAmount, from, shareAmount); } //============================== BEFORE TRANSFER HOOK =============================== /** * @notice Sets the share locker. * @notice If set to zero address, the share locker logic is disabled. * @dev Callable by OWNER_ROLE. */ function setBeforeTransferHook(address _hook) external requiresAuth { hook = BeforeTransferHook(_hook); } /** * @notice Call `beforeTransferHook` passing in `from` `to`, and `msg.sender`. */ function _callBeforeTransfer(address from, address to) internal view { if (address(hook) != address(0)) hook.beforeTransfer(from, to, msg.sender); } function transfer(address to, uint256 amount) public override returns (bool) { _callBeforeTransfer(msg.sender, to); return super.transfer(to, amount); } function transferFrom(address from, address to, uint256 amount) public override returns (bool) { _callBeforeTransfer(from, to); return super.transferFrom(from, to, amount); } //============================== RECEIVE =============================== receive() external payable {} } // File: lib/solmate/src/utils/MerkleProofLib.sol pragma solidity >=0.8.0; /// @notice Gas optimized merkle proof verification library. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol) /// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol) library MerkleProofLib { function verify( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool isValid) { /// @solidity memory-safe-assembly assembly { if proof.length { // Left shifting by 5 is like multiplying by 32. let end := add(proof.offset, shl(5, proof.length)) // Initialize offset to the offset of the proof in calldata. let offset := proof.offset // Iterate over proof elements to compute root hash. // prettier-ignore for {} 1 {} { // Slot where the leaf should be put in scratch space. If // leaf > calldataload(offset): slot 32, otherwise: slot 0. let leafSlot := shl(5, gt(leaf, calldataload(offset))) // Store elements to hash contiguously in scratch space. // The xor puts calldataload(offset) in whichever slot leaf // is not occupying, so 0 if leafSlot is 32, and 32 otherwise. mstore(leafSlot, leaf) mstore(xor(leafSlot, 32), calldataload(offset)) // Reuse leaf to store the hash to reduce stack operations. leaf := keccak256(0, 64) // Hash both slots of scratch space. offset := add(offset, 32) // Shift 1 word per cycle. // prettier-ignore if iszero(lt(offset, end)) { break } } } isValid := eq(leaf, root) // The proof is valid if the roots match. } } } // File: src/interfaces/DecoderCustomTypes.sol pragma solidity 0.8.21; contract DecoderCustomTypes { // ========================================= BALANCER ========================================= struct JoinPoolRequest { address[] assets; uint256[] maxAmountsIn; bytes userData; bool fromInternalBalance; } struct ExitPoolRequest { address[] assets; uint256[] minAmountsOut; bytes userData; bool toInternalBalance; } enum SwapKind { GIVEN_IN, GIVEN_OUT } struct SingleSwap { bytes32 poolId; SwapKind kind; address assetIn; address assetOut; uint256 amount; bytes userData; } struct FundManagement { address sender; bool fromInternalBalance; address recipient; bool toInternalBalance; } // ========================================= UNISWAP V3 ========================================= struct MintParams { address token0; address token1; uint24 fee; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; } struct IncreaseLiquidityParams { uint256 tokenId; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } struct DecreaseLiquidityParams { uint256 tokenId; uint128 liquidity; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } struct CollectParams { uint256 tokenId; address recipient; uint128 amount0Max; uint128 amount1Max; } struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } struct ExactInputParamsRouter02 { bytes path; address recipient; uint256 amountIn; uint256 amountOutMinimum; } struct PancakeSwapExactInputParams { bytes path; address recipient; uint256 amountIn; uint256 amountOutMinimum; } // ========================================= UNISWAP V4 ========================================= struct SwapParams { /// Whether to swap token0 for token1 or vice versa bool zeroForOne; /// The desired input amount if negative (exactIn), or the desired output amount if positive (exactOut) int256 amountSpecified; /// The sqrt price at which, if reached, the swap will stop executing uint160 sqrtPriceLimitX96; } struct PoolKey { /// @notice The lower currency of the pool, sorted numerically address currency0; /// @notice The higher currency of the pool, sorted numerically address currency1; /// @notice The pool LP fee, capped at 1_000_000. If the highest bit is 1, the pool has a dynamic fee and must be exactly equal to 0x800000 uint24 fee; /// @notice Ticks that involve positions must be a multiple of tick spacing int24 tickSpacing; /// @notice The hooks of the pool address hooks; } /// @dev comes from IV4 Router struct ExactInputSingleParams { PoolKey poolKey; bool zeroForOne; uint128 amountIn; uint128 amountOutMinimum; bytes hookData; } /// @notice Parameters for a single-hop exact-output swap struct ExactOutputSingleParams { PoolKey poolKey; bool zeroForOne; uint128 amountOut; uint128 amountInMaximum; bytes hookData; } // ========================================= MORPHO BLUE ========================================= struct MarketParams { address loanToken; address collateralToken; address oracle; address irm; uint256 lltv; } // ========================================= 1INCH ========================================= struct SwapDescription { address srcToken; address dstToken; address payable srcReceiver; address payable dstReceiver; uint256 amount; uint256 minReturnAmount; uint256 flags; } // ========================================= PENDLE ========================================= struct TokenInput { // TOKEN DATA address tokenIn; uint256 netTokenIn; address tokenMintSy; // AGGREGATOR DATA address pendleSwap; SwapData swapData; } struct TokenOutput { // TOKEN DATA address tokenOut; uint256 minTokenOut; address tokenRedeemSy; // AGGREGATOR DATA address pendleSwap; SwapData swapData; } struct ApproxParams { uint256 guessMin; uint256 guessMax; uint256 guessOffchain; // pass 0 in to skip this variable uint256 maxIteration; // every iteration, the diff between guessMin and guessMax will be divided by 2 uint256 eps; // the max eps between the returned result & the correct result, base 1e18. Normally this number will be set // to 1e15 (1e18/1000 = 0.1%) } struct SwapData { SwapType swapType; address extRouter; bytes extCalldata; bool needScale; } enum SwapType { NONE, KYBERSWAP, ONE_INCH, // ETH_WETH not used in Aggregator ETH_WETH } struct LimitOrderData { address limitRouter; uint256 epsSkipMarket; // only used for swap operations, will be ignored otherwise FillOrderParams[] normalFills; FillOrderParams[] flashFills; bytes optData; } struct FillOrderParams { Order order; bytes signature; uint256 makingAmount; } struct Order { uint256 salt; uint256 expiry; uint256 nonce; OrderType orderType; address token; address YT; address maker; address receiver; uint256 makingAmount; uint256 lnImpliedRate; uint256 failSafeRate; bytes permit; } enum OrderType { SY_FOR_PT, PT_FOR_SY, SY_FOR_YT, YT_FOR_SY } // ========================================= EIGEN LAYER ========================================= struct QueuedWithdrawalParams { // Array of strategies that the QueuedWithdrawal contains address[] strategies; // Array containing the amount of shares in each Strategy in the `strategies` array uint256[] shares; // The address of the withdrawer address withdrawer; } struct Withdrawal { // The address that originated the Withdrawal address staker; // The address that the staker was delegated to at the time that the Withdrawal was created address delegatedTo; // The address that can complete the Withdrawal + will receive funds when completing the withdrawal address withdrawer; // Nonce used to guarantee that otherwise identical withdrawals have unique hashes uint256 nonce; // Block number when the Withdrawal was created uint32 startBlock; // Array of strategies that the Withdrawal contains address[] strategies; // Array containing the amount of shares in each Strategy in the `strategies` array uint256[] shares; } struct SignatureWithExpiry { // the signature itself, formatted as a single bytes object bytes signature; // the expiration timestamp (UTC) of the signature uint256 expiry; } struct EarnerTreeMerkleLeaf { address earner; bytes32 earnerTokenRoot; } struct TokenTreeMerkleLeaf { address token; uint256 cumulativeEarnings; } struct RewardsMerkleClaim { uint32 rootIndex; uint32 earnerIndex; bytes earnerTreeProof; EarnerTreeMerkleLeaf earnerLeaf; uint32[] tokenIndices; bytes[] tokenTreeProofs; TokenTreeMerkleLeaf[] tokenLeaves; } // ========================================= CCIP ========================================= // If extraArgs is empty bytes, the default is 200k gas limit. struct EVM2AnyMessage { bytes receiver; // abi.encode(receiver address) for dest EVM chains bytes data; // Data payload EVMTokenAmount[] tokenAmounts; // Token transfers address feeToken; // Address of feeToken. address(0) means you will send msg.value. bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV2) } /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers. struct EVMTokenAmount { address token; // token address on the local chain. uint256 amount; // Amount of tokens. } struct EVMExtraArgsV1 { uint256 gasLimit; } // ========================================= OFT ========================================= struct SendParam { uint32 dstEid; // Destination endpoint ID. bytes32 to; // Recipient address. uint256 amountLD; // Amount to send in local decimals. uint256 minAmountLD; // Minimum amount to send in local decimals. bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message. bytes composeMsg; // The composed message for the send() operation. bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations. } struct MessagingFee { uint256 nativeFee; uint256 lzTokenFee; } // ========================================= L1StandardBridge ========================================= struct WithdrawalTransaction { uint256 nonce; address sender; address target; uint256 value; uint256 gasLimit; bytes data; } struct OutputRootProof { bytes32 version; bytes32 stateRoot; bytes32 messagePasserStorageRoot; bytes32 latestBlockhash; } // ========================================= Mantle L1StandardBridge ========================================= struct MantleWithdrawalTransaction { uint256 nonce; address sender; address target; uint256 mntValue; uint256 value; uint256 gasLimit; bytes data; } // ========================================= Linea Bridge ========================================= struct ClaimMessageWithProofParams { bytes32[] proof; uint256 messageNumber; uint32 leafIndex; address from; address to; uint256 fee; uint256 value; address payable feeRecipient; bytes32 merkleRoot; bytes data; } // ========================================= Scroll Bridge ========================================= struct L2MessageProof { uint256 batchIndex; bytes merkleProof; } // ========================================= Camelot V3 ========================================= struct CamelotMintParams { address token0; address token1; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; } // ========================================= Velodrome V3 ========================================= struct VelodromeMintParams { address token0; address token1; int24 tickSpacing; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; uint160 sqrtPriceX96; } // ========================================= Karak ========================================= struct QueuedWithdrawal { address staker; address delegatedTo; uint256 nonce; uint256 start; WithdrawRequest request; } struct WithdrawRequest { address[] vaults; uint256[] shares; address withdrawer; } // ========================================= Term Finance ================================== /// @dev TermAuctionOfferSubmission represents an offer submission to offeror an amount of money for a specific interest rate struct TermAuctionOfferSubmission { /// @dev For an existing offer this is the unique onchain identifier for this offer. For a new offer this is a randomized input that will be used to generate the unique onchain identifier. bytes32 id; /// @dev The address of the offeror address offeror; /// @dev Hash of the offered price as a percentage of the initial loaned amount vs amount returned at maturity. This stores 9 decimal places bytes32 offerPriceHash; /// @dev The maximum amount of purchase tokens that can be lent uint256 amount; /// @dev The address of the ERC20 purchase token address purchaseToken; } // ========================================= Dolomite Finance ================================== enum BalanceCheckFlag { Both, From, To, None } // ========================================= Silo Finance ================================== /// @dev There are 2 types of accounting in the system: for non-borrowable collateral deposit called "protected" and /// for borrowable collateral deposit called "collateral". System does /// identical calculations for each type of accounting but it uses different data. To avoid code duplication /// this enum is used to decide which data should be read. enum CollateralType { Protected, // default Collateral } enum ActionType { Deposit, Mint, Repay, RepayShares } struct Action { // what do you want to do? uint8 actionType; // which Silo are you interacting with? address silo; // what asset do you want to use? address asset; // options specific for actions bytes options; } struct AnyAction { // how much assets or shares do you want to use? uint256 amount; // are you using Protected, Collateral uint8 assetType; } // ========================================= LBTC Bridge ================================== struct DepositBridgeAction { uint256 fromChain; bytes32 fromContract; uint256 toChain; address toContract; address recipient; uint64 amount; uint256 nonce; } } // File: src/interfaces/BalancerVault.sol pragma solidity 0.8.21; interface BalancerVault { function flashLoan(address, address[] memory tokens, uint256[] memory amounts, bytes calldata userData) external; function swap( DecoderCustomTypes.SingleSwap memory singleSwap, DecoderCustomTypes.FundManagement memory funds, uint256 limit, uint256 deadline ) external returns (uint256 amountCalculated); } // File: src/interfaces/IPausable.sol pragma solidity 0.8.21; interface IPausable { function pause() external; function unpause() external; } // File: src/base/Drones/DroneLib.sol pragma solidity >=0.8.0; library DroneLib { bytes32 internal constant TARGET_FLAG = keccak256(bytes("DroneLib.target")); function extractTargetFromCalldata() internal pure returns (address target) { target = extractTargetFromInput(msg.data); } function extractTargetFromInput(bytes calldata data) internal pure returns (address target) { // Look at the last 32 bytes of calldata and see if the TARGET_FLAG is there. uint256 length = data.length; if (length >= 68) { bytes32 flag = bytes32(data[length - 32:]); if (flag == TARGET_FLAG) { // If the flag is there, extract the target from the calldata. target = address(bytes20(data[length - 52:length - 32])); } } // else no target present, so target is address(0). } } // File: src/base/Roles/ManagerWithMerkleVerification.sol pragma solidity 0.8.21; contract ManagerWithMerkleVerification is Auth, IPausable { using FixedPointMathLib for uint256; using SafeTransferLib for ERC20; using Address for address; // ========================================= STATE ========================================= /** * @notice A merkle tree root that restricts what data can be passed to the BoringVault. * @dev Maps a strategist address to their specific merkle root. * @dev Each leaf is composed of the keccak256 hash of abi.encodePacked {decodersAndSanitizer, target, valueIsNonZero, selector, argumentAddress_0, ...., argumentAddress_N} * Where: * - decodersAndSanitizer is the addres to call to extract packed address arguments from the calldata * - target is the address to make the call to * - valueIsNonZero is a bool indicating whether or not the value is non-zero * - selector is the function selector on target * - argumentAddress is each allowed address argument in that call */ mapping(address => bytes32) public manageRoot; /** * @notice Bool indicating whether or not this contract is actively performing a flash loan. * @dev Used to block flash loans that are initiated outside a manage call. */ bool internal performingFlashLoan; /** * @notice keccak256 hash of flash loan data. */ bytes32 internal flashLoanIntentHash = bytes32(0); /** * @notice Used to pause calls to `manageVaultWithMerkleVerification`. */ bool public isPaused; //============================== ERRORS =============================== error ManagerWithMerkleVerification__InvalidManageProofLength(); error ManagerWithMerkleVerification__InvalidTargetDataLength(); error ManagerWithMerkleVerification__InvalidValuesLength(); error ManagerWithMerkleVerification__InvalidDecodersAndSanitizersLength(); error ManagerWithMerkleVerification__FlashLoanNotExecuted(); error ManagerWithMerkleVerification__FlashLoanNotInProgress(); error ManagerWithMerkleVerification__BadFlashLoanIntentHash(); error ManagerWithMerkleVerification__FailedToVerifyManageProof(address target, bytes targetData, uint256 value); error ManagerWithMerkleVerification__Paused(); error ManagerWithMerkleVerification__OnlyCallableByBoringVault(); error ManagerWithMerkleVerification__OnlyCallableByBalancerVault(); error ManagerWithMerkleVerification__TotalSupplyMustRemainConstantDuringPlatform(); //============================== EVENTS =============================== event ManageRootUpdated(address indexed strategist, bytes32 oldRoot, bytes32 newRoot); event BoringVaultManaged(uint256 callsMade); event Paused(); event Unpaused(); //============================== IMMUTABLES =============================== /** * @notice The BoringVault this contract can manage. */ BoringVault public immutable vault; /** * @notice The balancer vault this contract can use for flash loans. */ BalancerVault public immutable balancerVault; constructor(address _owner, address _vault, address _balancerVault) Auth(_owner, Authority(address(0))) { vault = BoringVault(payable(_vault)); balancerVault = BalancerVault(_balancerVault); } // ========================================= ADMIN FUNCTIONS ========================================= /** * @notice Sets the manageRoot. * @dev Callable by OWNER_ROLE. */ function setManageRoot(address strategist, bytes32 _manageRoot) external requiresAuth { bytes32 oldRoot = manageRoot[strategist]; manageRoot[strategist] = _manageRoot; emit ManageRootUpdated(strategist, oldRoot, _manageRoot); } /** * @notice Pause this contract, which prevents future calls to `manageVaultWithMerkleVerification`. * @dev Callable by MULTISIG_ROLE. */ function pause() external requiresAuth { isPaused = true; emit Paused(); } /** * @notice Unpause this contract, which allows future calls to `manageVaultWithMerkleVerification`. * @dev Callable by MULTISIG_ROLE. */ function unpause() external requiresAuth { isPaused = false; emit Unpaused(); } // ========================================= STRATEGIST FUNCTIONS ========================================= /** * @notice Allows strategist to manage the BoringVault. * @dev The strategist must provide a merkle proof for every call that verifiees they are allowed to make that call. * @dev Callable by MANAGER_INTERNAL_ROLE. * @dev Callable by STRATEGIST_ROLE. * @dev Callable by MICRO_MANAGER_ROLE. */ function manageVaultWithMerkleVerification( bytes32[][] calldata manageProofs, address[] calldata decodersAndSanitizers, address[] calldata targets, bytes[] calldata targetData, uint256[] calldata values ) external requiresAuth { if (isPaused) revert ManagerWithMerkleVerification__Paused(); uint256 targetsLength = targets.length; if (targetsLength != manageProofs.length) revert ManagerWithMerkleVerification__InvalidManageProofLength(); if (targetsLength != targetData.length) revert ManagerWithMerkleVerification__InvalidTargetDataLength(); if (targetsLength != values.length) revert ManagerWithMerkleVerification__InvalidValuesLength(); if (targetsLength != decodersAndSanitizers.length) { revert ManagerWithMerkleVerification__InvalidDecodersAndSanitizersLength(); } bytes32 strategistManageRoot = manageRoot[msg.sender]; uint256 totalSupply = vault.totalSupply(); for (uint256 i; i < targetsLength; ++i) { _verifyCallData( strategistManageRoot, manageProofs[i], decodersAndSanitizers[i], targets[i], values[i], targetData[i] ); vault.manage(targets[i], targetData[i], values[i]); } if (totalSupply != vault.totalSupply()) { revert ManagerWithMerkleVerification__TotalSupplyMustRemainConstantDuringPlatform(); } emit BoringVaultManaged(targetsLength); } // ========================================= FLASH LOAN FUNCTIONS ========================================= /** * @notice In order to perform a flash loan, * 1) Merkle root must contain the leaf(address(this), this.flashLoan.selector, ARGUMENT_ADDRESSES ...) * 2) Strategist must initiate the flash loan using `manageVaultWithMerkleVerification` * 3) balancerVault MUST callback to this contract with the same userData */ function flashLoan( address recipient, address[] calldata tokens, uint256[] calldata amounts, bytes calldata userData ) external { if (msg.sender != address(vault)) revert ManagerWithMerkleVerification__OnlyCallableByBoringVault(); flashLoanIntentHash = keccak256(userData); performingFlashLoan = true; balancerVault.flashLoan(recipient, tokens, amounts, userData); performingFlashLoan = false; if (flashLoanIntentHash != bytes32(0)) revert ManagerWithMerkleVerification__FlashLoanNotExecuted(); } /** * @notice Add support for balancer flash loans. * @dev userData can optionally have salt encoded at the end of it, in order to change the intentHash, * if a flash loan is exact userData is being repeated, and their is fear of 3rd parties * front-running the rebalance. */ function receiveFlashLoan( address[] calldata tokens, uint256[] calldata amounts, uint256[] calldata feeAmounts, bytes calldata userData ) external { if (msg.sender != address(balancerVault)) revert ManagerWithMerkleVerification__OnlyCallableByBalancerVault(); if (!performingFlashLoan) revert ManagerWithMerkleVerification__FlashLoanNotInProgress(); // Validate userData using intentHash. bytes32 intentHash = keccak256(userData); if (intentHash != flashLoanIntentHash) revert ManagerWithMerkleVerification__BadFlashLoanIntentHash(); // reset intent hash to prevent replays. flashLoanIntentHash = bytes32(0); // Transfer tokens to vault. for (uint256 i = 0; i < amounts.length; ++i) { ERC20(tokens[i]).safeTransfer(address(vault), amounts[i]); } { ( bytes32[][] memory manageProofs, address[] memory decodersAndSanitizers, address[] memory targets, bytes[] memory data, uint256[] memory values ) = abi.decode(userData, (bytes32[][], address[], address[], bytes[], uint256[])); ManagerWithMerkleVerification(address(this)).manageVaultWithMerkleVerification( manageProofs, decodersAndSanitizers, targets, data, values ); } // Transfer tokens back to balancer. // Have vault transfer amount + fees back to balancer bytes[] memory transferData = new bytes[](amounts.length); for (uint256 i; i < amounts.length; ++i) { transferData[i] = abi.encodeWithSelector(ERC20.transfer.selector, address(balancerVault), (amounts[i] + feeAmounts[i])); } // Values is always zero, just pass in an array of zeroes. vault.manage(tokens, transferData, new uint256[](amounts.length)); } // ========================================= INTERNAL HELPER FUNCTIONS ========================================= /** * @notice Helper function to decode, sanitize, and verify call data. */ function _verifyCallData( bytes32 currentManageRoot, bytes32[] calldata manageProof, address decoderAndSanitizer, address target, uint256 value, bytes calldata targetData ) internal view { // Use address decoder to get addresses in call data. bytes memory packedArgumentAddresses = abi.decode(decoderAndSanitizer.functionStaticCall(targetData), (bytes)); address droneTarget = DroneLib.extractTargetFromInput(targetData); if (droneTarget != address(0)) { packedArgumentAddresses = abi.encodePacked(packedArgumentAddresses, droneTarget); } if ( !_verifyManageProof( currentManageRoot, manageProof, target, decoderAndSanitizer, value, bytes4(targetData), packedArgumentAddresses ) ) { revert ManagerWithMerkleVerification__FailedToVerifyManageProof(target, targetData, value); } } /** * @notice Helper function to verify a manageProof is valid. */ function _verifyManageProof( bytes32 root, bytes32[] calldata proof, address target, address decoderAndSanitizer, uint256 value, bytes4 selector, bytes memory packedArgumentAddresses ) internal pure returns (bool) { bool valueNonZero = value > 0; bytes32 leaf = keccak256(abi.encodePacked(decoderAndSanitizer, target, valueNonZero, selector, packedArgumentAddresses)); return MerkleProofLib.verify(proof, root, leaf); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_balancerVault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__BadFlashLoanIntentHash","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"targetData","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"ManagerWithMerkleVerification__FailedToVerifyManageProof","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__FlashLoanNotExecuted","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__FlashLoanNotInProgress","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__InvalidDecodersAndSanitizersLength","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__InvalidManageProofLength","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__InvalidTargetDataLength","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__InvalidValuesLength","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__OnlyCallableByBalancerVault","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__OnlyCallableByBoringVault","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__Paused","type":"error"},{"inputs":[],"name":"ManagerWithMerkleVerification__TotalSupplyMustRemainConstantDuringPlatform","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"callsMade","type":"uint256"}],"name":"BoringVaultManaged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategist","type":"address"},{"indexed":false,"internalType":"bytes32","name":"oldRoot","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"newRoot","type":"bytes32"}],"name":"ManageRootUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpaused","type":"event"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balancerVault","outputs":[{"internalType":"contract BalancerVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"flashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"manageRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[][]","name":"manageProofs","type":"bytes32[][]"},{"internalType":"address[]","name":"decodersAndSanitizers","type":"address[]"},{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"bytes[]","name":"targetData","type":"bytes[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"manageVaultWithMerkleVerification","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"feeAmounts","type":"uint256[]"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"receiveFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"strategist","type":"address"},{"internalType":"bytes32","name":"_manageRoot","type":"bytes32"}],"name":"setManageRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract BoringVault","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040525f60045534801562000014575f80fd5b506040516200223a3803806200223a8339810160408190526200003791620000f8565b5f80546001600160a01b0385166001600160a01b031991821681178355600180549092169091556040518592919033907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908490a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b76389980198905f90a350506001600160a01b039182166080521660a052506200013f565b80516001600160a01b0381168114620000f3575f80fd5b919050565b5f805f606084860312156200010b575f80fd5b6200011684620000dc565b92506200012660208501620000dc565b91506200013660408501620000dc565b90509250925092565b60805160a05161209b6200019f5f395f818160ee015281816107e3015281816109da0152610bed01525f8181610225015281816103da01528181610511015281816106170152818161076601528181610a8c0152610ccf015261209b5ff3fe608060405234801561000f575f80fd5b50600436106100e5575f3560e01c80638456cb5911610088578063bf7e214f11610063578063bf7e214f146101e7578063f04f2707146101fa578063f2fde38b1461020d578063fbfa77cf14610220575f80fd5b80638456cb59146101b05780638da5cb5b146101b8578063b187bd26146101ca575f80fd5b80633f4ba83a116100c35780633f4ba83a146101555780635c38449e1461015d5780635ca58a99146101705780637a9e5e4b1461019d575f80fd5b8063158274a5146100e957806321801a991461012d578063244b0f6a14610142575b5f80fd5b6101107f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61014061013b36600461128e565b610247565b005b6101406101503660046112ff565b6102df565b6101406106f6565b61014061016b366004611421565b61075b565b61018f61017e3660046114c5565b60026020525f908152604090205481565b604051908152602001610124565b6101406101ab3660046114c5565b610883565b610140610967565b5f54610110906001600160a01b031681565b6005546101d79060ff1681565b6040519015158152602001610124565b600154610110906001600160a01b031681565b6101406102083660046114e0565b6109cf565b61014061021b3660046114c5565b610da7565b6101107f000000000000000000000000000000000000000000000000000000000000000081565b61025c335f356001600160e01b031916610e22565b6102815760405162461bcd60e51b81526004016102789061159a565b60405180910390fd5b6001600160a01b0382165f81815260026020908152604091829020805490859055825181815291820185905292917f0b958dec85f1470000479dfb22c365829411f52bcde602d24ea0abf5ac7e8860910160405180910390a2505050565b6102f4335f356001600160e01b031916610e22565b6103105760405162461bcd60e51b81526004016102789061159a565b60055460ff161561033457604051631b7b196560e31b815260040160405180910390fd5b848981146103555760405163029c70cf60e41b815260040160405180910390fd5b8084146103755760405163581ddbfd60e01b815260040160405180910390fd5b8082146103955760405163e9fd1adf60e01b815260040160405180910390fd5b8088146103b557604051631b4d824d60e31b815260040160405180910390fd5b335f9081526002602090815260408083205481516318160ddd60e01b815291519093927f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316926318160ddd92600480830193928290030181865afa158015610427573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061044b91906115c0565b90505f5b838110156106145761050f838f8f8481811061046d5761046d6115d7565b905060200281019061047f91906115eb565b8f8f86818110610491576104916115d7565b90506020020160208101906104a691906114c5565b8e8e878181106104b8576104b86115d7565b90506020020160208101906104cd91906114c5565b8b8b888181106104df576104df6115d7565b905060200201358e8e898181106104f8576104f86115d7565b905060200281019061050a9190611630565b610eca565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f6e715d08b8b84818110610550576105506115d7565b905060200201602081019061056591906114c5565b8a8a85818110610577576105776115d7565b90506020028101906105899190611630565b8a8a8781811061059b5761059b6115d7565b905060200201356040518563ffffffff1660e01b81526004016105c1949392919061169a565b5f604051808303815f875af11580156105dc573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261060391908101906117aa565b5061060d816117ef565b905061044f565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610671573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069591906115c0565b81146106b457604051630ecee17560e01b815260040160405180910390fd5b6040518381527f53d426e7d80bb2c8674d3b45577e2d464d423faad6531b21f95ac11ac18b1cb69060200160405180910390a150505050505050505050505050565b61070b335f356001600160e01b031916610e22565b6107275760405162461bcd60e51b81526004016102789061159a565b6005805460ff191690556040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d16933905f90a1565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107a4576040516377ed816560e01b815260040160405180910390fd5b81816040516107b4929190611807565b60405190819003812060049081556003805460ff19166001179055632e1c224f60e11b82526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691635c38449e91610822918b918b918b918b918b918b918b910161185d565b5f604051808303815f87803b158015610839575f80fd5b505af115801561084b573d5f803e3d5ffd5b50506003805460ff1916905550506004541561087a57604051633de6ce8160e21b815260040160405180910390fd5b50505050505050565b5f546001600160a01b0316331480610914575060015460405163b700961360e01b81526001600160a01b039091169063b7009613906108d590339030906001600160e01b03195f3516906004016118d3565b602060405180830381865afa1580156108f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109149190611900565b61091c575f80fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b76389980198905f90a350565b61097c335f356001600160e01b031916610e22565b6109985760405162461bcd60e51b81526004016102789061159a565b6005805460ff191660011790556040517f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e752905f90a1565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a185760405163a38bce7f60e01b815260040160405180910390fd5b60035460ff16610a3b576040516326e6e2c760e01b815260040160405180910390fd5b5f8282604051610a4c929190611807565b604051809103902090506004548114610a7857604051631663f61360e01b815260040160405180910390fd5b5f60048190555b86811015610b0b57610afb7f0000000000000000000000000000000000000000000000000000000000000000898984818110610abd57610abd6115d7565b905060200201358c8c85818110610ad657610ad66115d7565b9050602002016020810190610aeb91906114c5565b6001600160a01b03169190610fb4565b610b04816117ef565b9050610a7f565b505f80808080610b1d87890189611b96565b60405163122587b560e11b815294995092975090955093509150309063244b0f6a90610b559088908890889088908890600401611d2e565b5f604051808303815f87803b158015610b6c575f80fd5b505af1158015610b7e573d5f803e3d5ffd5b5050505050505050505f878790506001600160401b03811115610ba357610ba36116cf565b604051908082528060200260200182016040528015610bd657816020015b6060815260200190600190039081610bc15790505b5090505f5b87811015610cc45763a9059cbb60e01b7f0000000000000000000000000000000000000000000000000000000000000000888884818110610c1e57610c1e6115d7565b905060200201358b8b85818110610c3757610c376115d7565b90506020020135610c489190611e09565b6040516001600160a01b0390921660248301526044820152606401604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050828281518110610ca857610ca86115d7565b602002602001018190525080610cbd906117ef565b9050610bdb565b506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663224d87038b8b848b6001600160401b03811115610d0f57610d0f6116cf565b604051908082528060200260200182016040528015610d38578160200160208202803683370190505b506040518563ffffffff1660e01b8152600401610d589493929190611e1c565b5f604051808303815f875af1158015610d73573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d9a9190810190611e60565b5050505050505050505050565b610dbc335f356001600160e01b031916610e22565b610dd85760405162461bcd60e51b81526004016102789061159a565b5f80546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6001545f906001600160a01b03168015801590610ea9575060405163b700961360e01b81526001600160a01b0382169063b700961390610e6a908790309088906004016118d3565b602060405180830381865afa158015610e85573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ea99190611900565b80610ec057505f546001600160a01b038581169116145b9150505b92915050565b5f610f1483838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250506001600160a01b038a1692915050611037565b806020019051810190610f2791906117aa565b90505f610f3484846110a9565b90506001600160a01b03811615610f6a578181604051602001610f58929190611f0a565b60405160208183030381529060405291505b610f838a8a8a898b8a610f7d8a8c611f3b565b89611163565b610fa8578584848760405163c0dcd1a760e01b8152600401610278949392919061169a565b50505050505050505050565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f5114161716915050806110315760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610278565b50505050565b60605f80846001600160a01b0316846040516110539190611f69565b5f60405180830381855afa9150503d805f811461108b576040519150601f19603f3d011682016040523d82523d5f602084013e611090565b606091505b50915091506110a08583836111b7565b95945050505050565b5f816044811061115c575f84846110c1602085611f84565b6110cc928290611f97565b6110d591611fbe565b60408051808201909152600f81526e111c9bdb99531a588b9d185c99d95d608a1b60209091015290507fc1b9dfe6c6d6343c26291b77edfcc5dbc62c3afa2ee72581da4e3cdbe96a0a4f810161115a578484611132603485611f84565b9061113e602086611f84565b9261114b93929190611f97565b61115491611fdb565b60601c92505b505b5092915050565b5f805f851190505f8688838787604051602001611184959493929190612009565b6040516020818303038152906040528051906020012090506111a88a8a8d84611216565b9b9a5050505050505050505050565b6060826111cc576111c78261124e565b61120f565b81511580156111e357506001600160a01b0384163b155b1561120c57604051639996b31560e01b81526001600160a01b0385166004820152602401610278565b50805b9392505050565b5f8315611246578360051b8501855b803580851160051b94855260209485185260405f2093018181106112255750505b501492915050565b80511561125e5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6001600160a01b0381168114611277575f80fd5b5f806040838503121561129f575f80fd5b82356112aa8161127a565b946020939093013593505050565b5f8083601f8401126112c8575f80fd5b5081356001600160401b038111156112de575f80fd5b6020830191508360208260051b85010111156112f8575f80fd5b9250929050565b5f805f805f805f805f8060a08b8d031215611318575f80fd5b8a356001600160401b038082111561132e575f80fd5b61133a8e838f016112b8565b909c509a5060208d0135915080821115611352575f80fd5b61135e8e838f016112b8565b909a50985060408d0135915080821115611376575f80fd5b6113828e838f016112b8565b909850965060608d013591508082111561139a575f80fd5b6113a68e838f016112b8565b909650945060808d01359150808211156113be575f80fd5b506113cb8d828e016112b8565b915080935050809150509295989b9194979a5092959850565b5f8083601f8401126113f4575f80fd5b5081356001600160401b0381111561140a575f80fd5b6020830191508360208285010111156112f8575f80fd5b5f805f805f805f6080888a031215611437575f80fd5b87356114428161127a565b965060208801356001600160401b038082111561145d575f80fd5b6114698b838c016112b8565b909850965060408a0135915080821115611481575f80fd5b61148d8b838c016112b8565b909650945060608a01359150808211156114a5575f80fd5b506114b28a828b016113e4565b989b979a50959850939692959293505050565b5f602082840312156114d5575f80fd5b813561120f8161127a565b5f805f805f805f806080898b0312156114f7575f80fd5b88356001600160401b038082111561150d575f80fd5b6115198c838d016112b8565b909a50985060208b0135915080821115611531575f80fd5b61153d8c838d016112b8565b909850965060408b0135915080821115611555575f80fd5b6115618c838d016112b8565b909650945060608b0135915080821115611579575f80fd5b506115868b828c016113e4565b999c989b5096995094979396929594505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b5f602082840312156115d0575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f808335601e19843603018112611600575f80fd5b8301803591506001600160401b03821115611619575f80fd5b6020019150600581901b36038213156112f8575f80fd5b5f808335601e19843603018112611645575f80fd5b8301803591506001600160401b0382111561165e575f80fd5b6020019150368190038213156112f8575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b6001600160a01b03851681526060602082018190525f906116be9083018587611672565b905082604083015295945050505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561170b5761170b6116cf565b604052919050565b5f6001600160401b0382111561172b5761172b6116cf565b50601f01601f191660200190565b5f5b8381101561175357818101518382015260200161173b565b50505f910152565b5f82601f83011261176a575f80fd5b815161177d61177882611713565b6116e3565b818152846020838601011115611791575f80fd5b6117a2826020830160208701611739565b949350505050565b5f602082840312156117ba575f80fd5b81516001600160401b038111156117cf575f80fd5b610ec08482850161175b565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611800576118006117db565b5060010190565b818382375f9101908152919050565b8183525f60208085019450825f5b858110156118525781356118378161127a565b6001600160a01b031687529582019590820190600101611824565b509495945050505050565b6001600160a01b03881681526080602082018190525f90611881908301888a611816565b82810360408401528581526001600160fb1b0386111561189f575f80fd5b8560051b8088602084013701828103602090810160608501526118c59082018587611672565b9a9950505050505050505050565b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b5f60208284031215611910575f80fd5b8151801515811461120f575f80fd5b5f6001600160401b03821115611937576119376116cf565b5060051b60200190565b5f82601f830112611950575f80fd5b813560206119606117788361191f565b828152600592831b850182019282820191908785111561197e575f80fd5b8387015b85811015611a0e5780356001600160401b038111156119a0575f8081fd5b8801603f81018a136119b1575f8081fd5b8581013560406119c36117788361191f565b82815291851b8301810191888101908d8411156119df575f8081fd5b938201935b838510156119fd578435825293890193908901906119e4565b885250505093850193508401611982565b5090979650505050505050565b5f82601f830112611a2a575f80fd5b81356020611a3a6117788361191f565b82815260059290921b84018101918181019086841115611a58575f80fd5b8286015b84811015611a7c578035611a6f8161127a565b8352918301918301611a5c565b509695505050505050565b5f82601f830112611a96575f80fd5b81356020611aa66117788361191f565b82815260059290921b84018101918181019086841115611ac4575f80fd5b8286015b84811015611a7c5780356001600160401b03811115611ae6575f8081fd5b8701603f81018913611af7575f8081fd5b848101356040611b0961177883611713565b8281528b82848601011115611b1d575f8081fd5b82828501898301375f92810188019290925250845250918301918301611ac8565b5f82601f830112611b4d575f80fd5b81356020611b5d6117788361191f565b82815260059290921b84018101918181019086841115611b7b575f80fd5b8286015b84811015611a7c5780358352918301918301611b7f565b5f805f805f60a08688031215611baa575f80fd5b85356001600160401b0380821115611bc0575f80fd5b611bcc89838a01611941565b96506020880135915080821115611be1575f80fd5b611bed89838a01611a1b565b95506040880135915080821115611c02575f80fd5b611c0e89838a01611a1b565b94506060880135915080821115611c23575f80fd5b611c2f89838a01611a87565b93506080880135915080821115611c44575f80fd5b50611c5188828901611b3e565b9150509295509295909350565b5f8151808452602080850194508084015f5b838110156118525781516001600160a01b031687529582019590820190600101611c70565b5f81518084526020808501808196508360051b810191508286015f5b85811015611cf357828403895281518051808652611cd481888801898501611739565b99860199601f01601f1916949094018501935090840190600101611cb1565b5091979650505050505050565b5f8151808452602080850194508084015f5b8381101561185257815187529582019590820190600101611d12565b5f60a0820160a0835280885180835260c08501915060c08160051b86010192506020808b015f805b84811015611daa5788870360bf19018652825180518089529085019085890190845b81811015611d9457835183529287019291870191600101611d78565b5090985050509483019491830191600101611d56565b50505085840381870152505050611dc18188611c5e565b90508281036040840152611dd58187611c5e565b90508281036060840152611de98186611c95565b90508281036080840152611dfd8185611d00565b98975050505050505050565b80820180821115610ec457610ec46117db565b606081525f611e2f606083018688611816565b8281036020840152611e418186611c95565b90508281036040840152611e558185611d00565b979650505050505050565b5f6020808385031215611e71575f80fd5b82516001600160401b0380821115611e87575f80fd5b818501915085601f830112611e9a575f80fd5b8151611ea86117788261191f565b81815260059190911b83018401908481019088831115611ec6575f80fd5b8585015b83811015611efd57805185811115611ee1575f8081fd5b611eef8b89838a010161175b565b845250918601918601611eca565b5098975050505050505050565b5f8351611f1b818460208801611739565b60609390931b6001600160601b0319169190920190815260140192915050565b6001600160e01b0319813581811691600485101561115a5760049490940360031b84901b1690921692915050565b5f8251611f7a818460208701611739565b9190910192915050565b81810381811115610ec457610ec46117db565b5f8085851115611fa5575f80fd5b83861115611fb1575f80fd5b5050820193919092039150565b80356020831015610ec4575f19602084900360031b1b1692915050565b6001600160601b0319813581811691601485101561115a5760149490940360031b84901b1690921692915050565b6001600160601b0319606087811b8216835286901b16601482015283151560f81b60288201526001600160e01b03198316602982015281515f9061205481602d850160208701611739565b91909101602d01969550505050505056fea2646970667358221220d4085813f4c1efdd3ee505e462b8bda5c8366371f4670da97da8021b5ac2ff9a64736f6c634300081500330000000000000000000000003b694d634981ace4b64a27c48bffe19f1447779b0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f2000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106100e5575f3560e01c80638456cb5911610088578063bf7e214f11610063578063bf7e214f146101e7578063f04f2707146101fa578063f2fde38b1461020d578063fbfa77cf14610220575f80fd5b80638456cb59146101b05780638da5cb5b146101b8578063b187bd26146101ca575f80fd5b80633f4ba83a116100c35780633f4ba83a146101555780635c38449e1461015d5780635ca58a99146101705780637a9e5e4b1461019d575f80fd5b8063158274a5146100e957806321801a991461012d578063244b0f6a14610142575b5f80fd5b6101107f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c881565b6040516001600160a01b0390911681526020015b60405180910390f35b61014061013b36600461128e565b610247565b005b6101406101503660046112ff565b6102df565b6101406106f6565b61014061016b366004611421565b61075b565b61018f61017e3660046114c5565b60026020525f908152604090205481565b604051908152602001610124565b6101406101ab3660046114c5565b610883565b610140610967565b5f54610110906001600160a01b031681565b6005546101d79060ff1681565b6040519015158152602001610124565b600154610110906001600160a01b031681565b6101406102083660046114e0565b6109cf565b61014061021b3660046114c5565b610da7565b6101107f0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f281565b61025c335f356001600160e01b031916610e22565b6102815760405162461bcd60e51b81526004016102789061159a565b60405180910390fd5b6001600160a01b0382165f81815260026020908152604091829020805490859055825181815291820185905292917f0b958dec85f1470000479dfb22c365829411f52bcde602d24ea0abf5ac7e8860910160405180910390a2505050565b6102f4335f356001600160e01b031916610e22565b6103105760405162461bcd60e51b81526004016102789061159a565b60055460ff161561033457604051631b7b196560e31b815260040160405180910390fd5b848981146103555760405163029c70cf60e41b815260040160405180910390fd5b8084146103755760405163581ddbfd60e01b815260040160405180910390fd5b8082146103955760405163e9fd1adf60e01b815260040160405180910390fd5b8088146103b557604051631b4d824d60e31b815260040160405180910390fd5b335f9081526002602090815260408083205481516318160ddd60e01b815291519093927f0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f26001600160a01b0316926318160ddd92600480830193928290030181865afa158015610427573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061044b91906115c0565b90505f5b838110156106145761050f838f8f8481811061046d5761046d6115d7565b905060200281019061047f91906115eb565b8f8f86818110610491576104916115d7565b90506020020160208101906104a691906114c5565b8e8e878181106104b8576104b86115d7565b90506020020160208101906104cd91906114c5565b8b8b888181106104df576104df6115d7565b905060200201358e8e898181106104f8576104f86115d7565b905060200281019061050a9190611630565b610eca565b7f0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f26001600160a01b031663f6e715d08b8b84818110610550576105506115d7565b905060200201602081019061056591906114c5565b8a8a85818110610577576105776115d7565b90506020028101906105899190611630565b8a8a8781811061059b5761059b6115d7565b905060200201356040518563ffffffff1660e01b81526004016105c1949392919061169a565b5f604051808303815f875af11580156105dc573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261060391908101906117aa565b5061060d816117ef565b905061044f565b507f0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f26001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610671573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069591906115c0565b81146106b457604051630ecee17560e01b815260040160405180910390fd5b6040518381527f53d426e7d80bb2c8674d3b45577e2d464d423faad6531b21f95ac11ac18b1cb69060200160405180910390a150505050505050505050505050565b61070b335f356001600160e01b031916610e22565b6107275760405162461bcd60e51b81526004016102789061159a565b6005805460ff191690556040517fa45f47fdea8a1efdd9029a5691c7f759c32b7c698632b563573e155625d16933905f90a1565b336001600160a01b037f0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f216146107a4576040516377ed816560e01b815260040160405180910390fd5b81816040516107b4929190611807565b60405190819003812060049081556003805460ff19166001179055632e1c224f60e11b82526001600160a01b037f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c81691635c38449e91610822918b918b918b918b918b918b918b910161185d565b5f604051808303815f87803b158015610839575f80fd5b505af115801561084b573d5f803e3d5ffd5b50506003805460ff1916905550506004541561087a57604051633de6ce8160e21b815260040160405180910390fd5b50505050505050565b5f546001600160a01b0316331480610914575060015460405163b700961360e01b81526001600160a01b039091169063b7009613906108d590339030906001600160e01b03195f3516906004016118d3565b602060405180830381865afa1580156108f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109149190611900565b61091c575f80fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b76389980198905f90a350565b61097c335f356001600160e01b031916610e22565b6109985760405162461bcd60e51b81526004016102789061159a565b6005805460ff191660011790556040517f9e87fac88ff661f02d44f95383c817fece4bce600a3dab7a54406878b965e752905f90a1565b336001600160a01b037f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c81614610a185760405163a38bce7f60e01b815260040160405180910390fd5b60035460ff16610a3b576040516326e6e2c760e01b815260040160405180910390fd5b5f8282604051610a4c929190611807565b604051809103902090506004548114610a7857604051631663f61360e01b815260040160405180910390fd5b5f60048190555b86811015610b0b57610afb7f0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f2898984818110610abd57610abd6115d7565b905060200201358c8c85818110610ad657610ad66115d7565b9050602002016020810190610aeb91906114c5565b6001600160a01b03169190610fb4565b610b04816117ef565b9050610a7f565b505f80808080610b1d87890189611b96565b60405163122587b560e11b815294995092975090955093509150309063244b0f6a90610b559088908890889088908890600401611d2e565b5f604051808303815f87803b158015610b6c575f80fd5b505af1158015610b7e573d5f803e3d5ffd5b5050505050505050505f878790506001600160401b03811115610ba357610ba36116cf565b604051908082528060200260200182016040528015610bd657816020015b6060815260200190600190039081610bc15790505b5090505f5b87811015610cc45763a9059cbb60e01b7f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8888884818110610c1e57610c1e6115d7565b905060200201358b8b85818110610c3757610c376115d7565b90506020020135610c489190611e09565b6040516001600160a01b0390921660248301526044820152606401604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050828281518110610ca857610ca86115d7565b602002602001018190525080610cbd906117ef565b9050610bdb565b506001600160a01b037f0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f21663224d87038b8b848b6001600160401b03811115610d0f57610d0f6116cf565b604051908082528060200260200182016040528015610d38578160200160208202803683370190505b506040518563ffffffff1660e01b8152600401610d589493929190611e1c565b5f604051808303815f875af1158015610d73573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d9a9190810190611e60565b5050505050505050505050565b610dbc335f356001600160e01b031916610e22565b610dd85760405162461bcd60e51b81526004016102789061159a565b5f80546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6001545f906001600160a01b03168015801590610ea9575060405163b700961360e01b81526001600160a01b0382169063b700961390610e6a908790309088906004016118d3565b602060405180830381865afa158015610e85573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ea99190611900565b80610ec057505f546001600160a01b038581169116145b9150505b92915050565b5f610f1483838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250506001600160a01b038a1692915050611037565b806020019051810190610f2791906117aa565b90505f610f3484846110a9565b90506001600160a01b03811615610f6a578181604051602001610f58929190611f0a565b60405160208183030381529060405291505b610f838a8a8a898b8a610f7d8a8c611f3b565b89611163565b610fa8578584848760405163c0dcd1a760e01b8152600401610278949392919061169a565b50505050505050505050565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f5114161716915050806110315760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610278565b50505050565b60605f80846001600160a01b0316846040516110539190611f69565b5f60405180830381855afa9150503d805f811461108b576040519150601f19603f3d011682016040523d82523d5f602084013e611090565b606091505b50915091506110a08583836111b7565b95945050505050565b5f816044811061115c575f84846110c1602085611f84565b6110cc928290611f97565b6110d591611fbe565b60408051808201909152600f81526e111c9bdb99531a588b9d185c99d95d608a1b60209091015290507fc1b9dfe6c6d6343c26291b77edfcc5dbc62c3afa2ee72581da4e3cdbe96a0a4f810161115a578484611132603485611f84565b9061113e602086611f84565b9261114b93929190611f97565b61115491611fdb565b60601c92505b505b5092915050565b5f805f851190505f8688838787604051602001611184959493929190612009565b6040516020818303038152906040528051906020012090506111a88a8a8d84611216565b9b9a5050505050505050505050565b6060826111cc576111c78261124e565b61120f565b81511580156111e357506001600160a01b0384163b155b1561120c57604051639996b31560e01b81526001600160a01b0385166004820152602401610278565b50805b9392505050565b5f8315611246578360051b8501855b803580851160051b94855260209485185260405f2093018181106112255750505b501492915050565b80511561125e5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6001600160a01b0381168114611277575f80fd5b5f806040838503121561129f575f80fd5b82356112aa8161127a565b946020939093013593505050565b5f8083601f8401126112c8575f80fd5b5081356001600160401b038111156112de575f80fd5b6020830191508360208260051b85010111156112f8575f80fd5b9250929050565b5f805f805f805f805f8060a08b8d031215611318575f80fd5b8a356001600160401b038082111561132e575f80fd5b61133a8e838f016112b8565b909c509a5060208d0135915080821115611352575f80fd5b61135e8e838f016112b8565b909a50985060408d0135915080821115611376575f80fd5b6113828e838f016112b8565b909850965060608d013591508082111561139a575f80fd5b6113a68e838f016112b8565b909650945060808d01359150808211156113be575f80fd5b506113cb8d828e016112b8565b915080935050809150509295989b9194979a5092959850565b5f8083601f8401126113f4575f80fd5b5081356001600160401b0381111561140a575f80fd5b6020830191508360208285010111156112f8575f80fd5b5f805f805f805f6080888a031215611437575f80fd5b87356114428161127a565b965060208801356001600160401b038082111561145d575f80fd5b6114698b838c016112b8565b909850965060408a0135915080821115611481575f80fd5b61148d8b838c016112b8565b909650945060608a01359150808211156114a5575f80fd5b506114b28a828b016113e4565b989b979a50959850939692959293505050565b5f602082840312156114d5575f80fd5b813561120f8161127a565b5f805f805f805f806080898b0312156114f7575f80fd5b88356001600160401b038082111561150d575f80fd5b6115198c838d016112b8565b909a50985060208b0135915080821115611531575f80fd5b61153d8c838d016112b8565b909850965060408b0135915080821115611555575f80fd5b6115618c838d016112b8565b909650945060608b0135915080821115611579575f80fd5b506115868b828c016113e4565b999c989b5096995094979396929594505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b5f602082840312156115d0575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f808335601e19843603018112611600575f80fd5b8301803591506001600160401b03821115611619575f80fd5b6020019150600581901b36038213156112f8575f80fd5b5f808335601e19843603018112611645575f80fd5b8301803591506001600160401b0382111561165e575f80fd5b6020019150368190038213156112f8575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b6001600160a01b03851681526060602082018190525f906116be9083018587611672565b905082604083015295945050505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561170b5761170b6116cf565b604052919050565b5f6001600160401b0382111561172b5761172b6116cf565b50601f01601f191660200190565b5f5b8381101561175357818101518382015260200161173b565b50505f910152565b5f82601f83011261176a575f80fd5b815161177d61177882611713565b6116e3565b818152846020838601011115611791575f80fd5b6117a2826020830160208701611739565b949350505050565b5f602082840312156117ba575f80fd5b81516001600160401b038111156117cf575f80fd5b610ec08482850161175b565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611800576118006117db565b5060010190565b818382375f9101908152919050565b8183525f60208085019450825f5b858110156118525781356118378161127a565b6001600160a01b031687529582019590820190600101611824565b509495945050505050565b6001600160a01b03881681526080602082018190525f90611881908301888a611816565b82810360408401528581526001600160fb1b0386111561189f575f80fd5b8560051b8088602084013701828103602090810160608501526118c59082018587611672565b9a9950505050505050505050565b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b5f60208284031215611910575f80fd5b8151801515811461120f575f80fd5b5f6001600160401b03821115611937576119376116cf565b5060051b60200190565b5f82601f830112611950575f80fd5b813560206119606117788361191f565b828152600592831b850182019282820191908785111561197e575f80fd5b8387015b85811015611a0e5780356001600160401b038111156119a0575f8081fd5b8801603f81018a136119b1575f8081fd5b8581013560406119c36117788361191f565b82815291851b8301810191888101908d8411156119df575f8081fd5b938201935b838510156119fd578435825293890193908901906119e4565b885250505093850193508401611982565b5090979650505050505050565b5f82601f830112611a2a575f80fd5b81356020611a3a6117788361191f565b82815260059290921b84018101918181019086841115611a58575f80fd5b8286015b84811015611a7c578035611a6f8161127a565b8352918301918301611a5c565b509695505050505050565b5f82601f830112611a96575f80fd5b81356020611aa66117788361191f565b82815260059290921b84018101918181019086841115611ac4575f80fd5b8286015b84811015611a7c5780356001600160401b03811115611ae6575f8081fd5b8701603f81018913611af7575f8081fd5b848101356040611b0961177883611713565b8281528b82848601011115611b1d575f8081fd5b82828501898301375f92810188019290925250845250918301918301611ac8565b5f82601f830112611b4d575f80fd5b81356020611b5d6117788361191f565b82815260059290921b84018101918181019086841115611b7b575f80fd5b8286015b84811015611a7c5780358352918301918301611b7f565b5f805f805f60a08688031215611baa575f80fd5b85356001600160401b0380821115611bc0575f80fd5b611bcc89838a01611941565b96506020880135915080821115611be1575f80fd5b611bed89838a01611a1b565b95506040880135915080821115611c02575f80fd5b611c0e89838a01611a1b565b94506060880135915080821115611c23575f80fd5b611c2f89838a01611a87565b93506080880135915080821115611c44575f80fd5b50611c5188828901611b3e565b9150509295509295909350565b5f8151808452602080850194508084015f5b838110156118525781516001600160a01b031687529582019590820190600101611c70565b5f81518084526020808501808196508360051b810191508286015f5b85811015611cf357828403895281518051808652611cd481888801898501611739565b99860199601f01601f1916949094018501935090840190600101611cb1565b5091979650505050505050565b5f8151808452602080850194508084015f5b8381101561185257815187529582019590820190600101611d12565b5f60a0820160a0835280885180835260c08501915060c08160051b86010192506020808b015f805b84811015611daa5788870360bf19018652825180518089529085019085890190845b81811015611d9457835183529287019291870191600101611d78565b5090985050509483019491830191600101611d56565b50505085840381870152505050611dc18188611c5e565b90508281036040840152611dd58187611c5e565b90508281036060840152611de98186611c95565b90508281036080840152611dfd8185611d00565b98975050505050505050565b80820180821115610ec457610ec46117db565b606081525f611e2f606083018688611816565b8281036020840152611e418186611c95565b90508281036040840152611e558185611d00565b979650505050505050565b5f6020808385031215611e71575f80fd5b82516001600160401b0380821115611e87575f80fd5b818501915085601f830112611e9a575f80fd5b8151611ea86117788261191f565b81815260059190911b83018401908481019088831115611ec6575f80fd5b8585015b83811015611efd57805185811115611ee1575f8081fd5b611eef8b89838a010161175b565b845250918601918601611eca565b5098975050505050505050565b5f8351611f1b818460208801611739565b60609390931b6001600160601b0319169190920190815260140192915050565b6001600160e01b0319813581811691600485101561115a5760049490940360031b84901b1690921692915050565b5f8251611f7a818460208701611739565b9190910192915050565b81810381811115610ec457610ec46117db565b5f8085851115611fa5575f80fd5b83861115611fb1575f80fd5b5050820193919092039150565b80356020831015610ec4575f19602084900360031b1b1692915050565b6001600160601b0319813581811691601485101561115a5760149490940360031b84901b1690921692915050565b6001600160601b0319606087811b8216835286901b16601482015283151560f81b60288201526001600160e01b03198316602982015281515f9061205481602d850160208701611739565b91909101602d01969550505050505056fea2646970667358221220d4085813f4c1efdd3ee505e462b8bda5c8366371f4670da97da8021b5ac2ff9a64736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003b694d634981ace4b64a27c48bffe19f1447779b0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f2000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8
-----Decoded View---------------
Arg [0] : _owner (address): 0x3B694d634981Ace4B64a27c48bffe19f1447779B
Arg [1] : _vault (address): 0x6E575AE5e1A12e910641183F555Fad62eD1481F2
Arg [2] : _balancerVault (address): 0xBA12222222228d8Ba445958a75a0704d566BF2C8
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000003b694d634981ace4b64a27c48bffe19f1447779b
Arg [1] : 0000000000000000000000006e575ae5e1a12e910641183f555fad62ed1481f2
Arg [2] : 000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8
Deployed Bytecode Sourcemap
64974:11770:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68135:44;;;;;;;;-1:-1:-1;;;;;200:32:1;;;182:51;;170:2;155:18;68135:44:0;;;;;;;;68613:259;;;;;;:::i;:::-;;:::i;:::-;;69872:1526;;;;;;:::i;:::-;;:::i;69311:102::-;;;:::i;71894:599::-;;;;;;:::i;:::-;;:::i;66061:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;4938:25:1;;;4926:2;4911:18;66061:45:0;4792:177:1;39837:442:0;;;;;;:::i;:::-;;:::i;69043:97::-;;;:::i;38850:20::-;;;;;-1:-1:-1;;;;;38850:20:0;;;66575;;;;;;;;;;;;5617:14:1;;5610:22;5592:41;;5580:2;5565:18;66575:20:0;5452:187:1;38879:26:0;;;;;-1:-1:-1;;;;;38879:26:0;;;72822:1987;;;;;;:::i;:::-;;:::i;40287:168::-;;;;;;:::i;:::-;;:::i;68000:34::-;;;;;68613:259;39203:33;39216:10;39228:7;;-1:-1:-1;;;;;;39228:7:0;39203:12;:33::i;:::-;39195:58;;;;-1:-1:-1;;;39195:58:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;68728:22:0;::::1;68710:15;68728:22:::0;;;:10:::1;:22;::::0;;;;;;;;;;68761:36;;;;68813:51;;8059:25:1;;;8100:18;;;8093:34;;;68728:22:0;;68813:51:::1;::::0;8032:18:1;68813:51:0::1;;;;;;;68699:173;68613:259:::0;;:::o;69872:1526::-;39203:33;39216:10;39228:7;;-1:-1:-1;;;;;;39228:7:0;39203:12;:33::i;:::-;39195:58;;;;-1:-1:-1;;;39195:58:0;;;;;;;:::i;:::-;70165:8:::1;::::0;::::1;;70161:60;;;70182:39;;-1:-1:-1::0;;;70182:39:0::1;;;;;;;;;;;70161:60;70256:7:::0;70285:36;;::::1;70281:106;;70330:57;;-1:-1:-1::0;;;70330:57:0::1;;;;;;;;;;;70281:106;70402:34:::0;;::::1;70398:103;;70445:56;;-1:-1:-1::0;;;70445:56:0::1;;;;;;;;;;;70398:103;70516:30:::0;;::::1;70512:95;;70555:52;;-1:-1:-1::0;;;70555:52:0::1;;;;;;;;;;;70512:95;70622:45:::0;;::::1;70618:152;;70691:67;;-1:-1:-1::0;;;70691:67:0::1;;;;;;;;;;;70618:152;70824:10;70782:28;70813:22:::0;;;:10:::1;:22;::::0;;;;;;;;70868:19;;-1:-1:-1;;;70868:19:0;;;;70813:22;;70782:28;70868:5:::1;-1:-1:-1::0;;;;;70868:17:0::1;::::0;::::1;::::0;:19:::1;::::0;;::::1;::::0;70813:22;70868:19;;;;;:17;:19:::1;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70846:41;;70905:9;70900:282;70920:13;70916:1;:17;70900:282;;;70955:150;70989:20;71011:12;;71024:1;71011:15;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;71028:21;;71050:1;71028:24;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;71054:7;;71062:1;71054:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;71066:6;;71073:1;71066:9;;;;;;;:::i;:::-;;;;;;;71077:10;;71088:1;71077:13;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;70955:15;:150::i;:::-;71120:5;-1:-1:-1::0;;;;;71120:12:0::1;;71133:7;;71141:1;71133:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;71145;;71156:1;71145:13;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;71160:6;;71167:1;71160:9;;;;;;;:::i;:::-;;;;;;;71120:50;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;71120:50:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;70935:3:0::1;::::0;::::1;:::i;:::-;;;70900:282;;;;71211:5;-1:-1:-1::0;;;;;71211:17:0::1;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71196:11;:34;71192:150;;71254:76;;-1:-1:-1::0;;;71254:76:0::1;;;;;;;;;;;71192:150;71357:33;::::0;4938:25:1;;;71357:33:0::1;::::0;4926:2:1;4911:18;71357:33:0::1;;;;;;;70150:1248;;;69872:1526:::0;;;;;;;;;;:::o;69311:102::-;39203:33;39216:10;39228:7;;-1:-1:-1;;;;;;39228:7:0;39203:12;:33::i;:::-;39195:58;;;;-1:-1:-1;;;39195:58:0;;;;;;;:::i;:::-;69363:8:::1;:16:::0;;-1:-1:-1;;69363:16:0::1;::::0;;69395:10:::1;::::0;::::1;::::0;69374:5:::1;::::0;69395:10:::1;69311:102::o:0;71894:599::-;72079:10;-1:-1:-1;;;;;72101:5:0;72079:28;;72075:99;;72116:58;;-1:-1:-1;;;72116:58:0;;;;;;;;;;;72075:99;72219:8;;72209:19;;;;;;;:::i;:::-;;;;;;;;;72187;:41;;;72239:19;:26;;-1:-1:-1;;72239:26:0;72261:4;72239:26;;;-1:-1:-1;;;72276:61:0;;-1:-1:-1;;;;;72276:13:0;:23;;;;:61;;72300:9;;72311:6;;;;72319:7;;;;72328:8;;;;72276:61;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;72348:19:0;:27;;-1:-1:-1;;72348:27:0;;;-1:-1:-1;;72390:19:0;;:33;72386:99;;72432:53;;-1:-1:-1;;;72432:53:0;;;;;;;;;;;72386:99;71894:599;;;;;;;:::o;39837:442::-;40111:5;;-1:-1:-1;;;;;40111:5:0;40097:10;:19;;:76;;-1:-1:-1;40120:9:0;;:53;;-1:-1:-1;;;40120:53:0;;-1:-1:-1;;;;;40120:9:0;;;;:17;;:53;;40138:10;;40158:4;;-1:-1:-1;;;;;;40120:9:0;40165:7;;;40120:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40089:85;;;;;;40187:9;:24;;-1:-1:-1;;;;;;40187:24:0;-1:-1:-1;;;;;40187:24:0;;;;;;;;40229:42;;40246:10;;40229:42;;-1:-1:-1;;40229:42:0;39837:442;:::o;69043:97::-;39203:33;39216:10;39228:7;;-1:-1:-1;;;;;;39228:7:0;39203:12;:33::i;:::-;39195:58;;;;-1:-1:-1;;;39195:58:0;;;;;;;:::i;:::-;69093:8:::1;:15:::0;;-1:-1:-1;;69093:15:0::1;69104:4;69093:15;::::0;;69124:8:::1;::::0;::::1;::::0;69093::::1;::::0;69124::::1;69043:97::o:0;72822:1987::-;73026:10;-1:-1:-1;;;;;73048:13:0;73026:36;;73022:109;;73071:60;;-1:-1:-1;;;73071:60:0;;;;;;;;;;;73022:109;73147:19;;;;73142:88;;73175:55;;-1:-1:-1;;;73175:55:0;;;;;;;;;;;73142:88;73291:18;73322:8;;73312:19;;;;;;;:::i;:::-;;;;;;;;73291:40;;73360:19;;73346:10;:33;73342:101;;73388:55;;-1:-1:-1;;;73388:55:0;;;;;;;;;;;73342:101;73534:1;73504:19;:32;;;73587:129;73607:18;;;73587:129;;;73647:57;73685:5;73693:7;;73701:1;73693:10;;;;;;;:::i;:::-;;;;;;;73653:6;;73660:1;73653:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;73647:29:0;;:57;:29;:57::i;:::-;73627:3;;;:::i;:::-;;;73587:129;;;-1:-1:-1;73760:31:0;;;;;73989:77;;;;74000:8;73989:77;:::i;:::-;74083:170;;-1:-1:-1;;;74083:170:0;;73741:325;;-1:-1:-1;73741:325:0;;-1:-1:-1;73741:325:0;;-1:-1:-1;73741:325:0;-1:-1:-1;73741:325:0;-1:-1:-1;74121:4:0;;74083:78;;:170;;73741:325;;;;;;;;;;74083:170;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73726:539;;;;;74386:27;74428:7;;:14;;-1:-1:-1;;;;;74416:27:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74386:57;;74459:9;74454:204;74470:18;;;74454:204;;;-1:-1:-1;;;74601:13:0;74631:10;;74642:1;74631:13;;;;;;;:::i;:::-;;;;;;;74618:7;;74626:1;74618:10;;;;;;;:::i;:::-;;;;;;;:26;;;;:::i;:::-;74545:101;;-1:-1:-1;;;;;25062:32:1;;;74545:101:0;;;25044:51:1;25111:18;;;25104:34;25017:18;;74545:101:0;;;;;;;;;;;;;-1:-1:-1;;;;;74545:101:0;;;;;;;-1:-1:-1;;;;;74545:101:0;;;;;;;;;;;74510:12;74523:1;74510:15;;;;;;;;:::i;:::-;;;;;;:136;;;;74490:3;;;;:::i;:::-;;;74454:204;;;-1:-1:-1;;;;;;74736:5:0;:12;;74749:6;;74757:12;74785:7;-1:-1:-1;;;;;74771:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74771:29:0;;74736:65;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74736:65:0;;;;;;;;;;;;:::i;:::-;;73011:1798;;72822:1987;;;;;;;;:::o;40287:168::-;39203:33;39216:10;39228:7;;-1:-1:-1;;;;;;39228:7:0;39203:12;:33::i;:::-;39195:58;;;;-1:-1:-1;;;39195:58:0;;;;;;;:::i;:::-;40371:5:::1;:16:::0;;-1:-1:-1;;;;;;40371:16:0::1;-1:-1:-1::0;;;;;40371:16:0;::::1;::::0;;::::1;::::0;;40405:42:::1;::::0;40371:16;;40426:10:::1;::::0;40405:42:::1;::::0;40371:5;40405:42:::1;40287:168:::0;:::o;39283:546::-;39404:9;;39370:4;;-1:-1:-1;;;;;39404:9:0;39726:27;;;;;:77;;-1:-1:-1;39757:46:0;;-1:-1:-1;;;39757:46:0;;-1:-1:-1;;;;;39757:12:0;;;;;:46;;39770:4;;39784;;39791:11;;39757:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39725:96;;;-1:-1:-1;39816:5:0;;-1:-1:-1;;;;;39808:13:0;;;39816:5;;39808:13;39725:96;39718:103;;;39283:546;;;;;:::o;75030:1087::-;75350:36;75400:50;75439:10;;75400:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;75400:38:0;;;:50;-1:-1:-1;;75400:38:0;:50::i;:::-;75389:71;;;;;;;;;;;;:::i;:::-;75350:110;;75471:19;75493:43;75525:10;;75493:31;:43::i;:::-;75471:65;-1:-1:-1;;;;;;75551:25:0;;;75547:138;;75636:23;75661:11;75619:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75593:80;;75547:138;75716:265;75753:17;75789:11;;75819:6;75844:19;75882:5;75906:18;75913:10;;75906:18;:::i;:::-;75943:23;75716:18;:265::i;:::-;75697:413;;76072:6;76080:10;;76092:5;76015:83;;-1:-1:-1;;;76015:83:0;;;;;;;;;;;:::i;75697:413::-;75276:841;;75030:1087;;;;;;;;:::o;34785:1637::-;34902:12;35077:4;35071:11;-1:-1:-1;;;35203:17:0;35196:93;-1:-1:-1;;;;;35341:2:0;35337:51;35333:1;35314:17;35310:25;35303:86;35476:6;35471:2;35452:17;35448:26;35441:42;36338:2;36335:1;36331:2;36312:17;36309:1;36302:5;36295;36290:51;35854:16;35847:24;35841:2;35823:16;35820:24;35816:1;35812;35806:8;35803:15;35799:46;35796:76;35593:763;35582:774;;;36387:7;36379:35;;;;-1:-1:-1;;;36379:35:0;;27976:2:1;36379:35:0;;;27958:21:1;28015:2;27995:18;;;27988:30;-1:-1:-1;;;28034:18:1;;;28027:45;28089:18;;36379:35:0;27774:339:1;36379:35:0;34891:1531;34785:1637;;;:::o;14238:257::-;14324:12;14350;14364:23;14391:6;-1:-1:-1;;;;;14391:17:0;14409:4;14391:23;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14349:65;;;;14432:55;14459:6;14467:7;14476:10;14432:26;:55::i;:::-;14425:62;14238:257;-1:-1:-1;;;;;14238:257:0:o;64259:598::-;64335:14;64466:4;64502:2;64492:12;;64488:299;;64521:12;64544:4;;64549:11;64558:2;64549:6;:11;:::i;:::-;64544:18;;;;;:::i;:::-;64536:27;;;:::i;:::-;64081:24;;;;;;;;;;;;-1:-1:-1;;;64081:24:0;;;;;64521:42;-1:-1:-1;64584:19:0;;;64580:196;;64729:4;;64734:11;64743:2;64734:6;:11;:::i;:::-;64729:29;64746:11;64755:2;64746:6;:11;:::i;:::-;64729:29;;;;;;;:::i;:::-;64721:38;;;:::i;:::-;64713:47;;64704:56;;64580:196;64506:281;64488:299;64351:506;64259:598;;;;:::o;76209:532::-;76485:4;76502:17;76530:1;76522:5;:9;76502:29;;76542:12;76597:19;76618:6;76626:12;76640:8;76650:23;76580:94;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;76570:105;;;;;;76542:133;;76693:40;76715:5;;76722:4;76728;76693:21;:40::i;:::-;76686:47;76209:532;-1:-1:-1;;;;;;;;;;;76209:532:0:o;15171:597::-;15319:12;15349:7;15344:417;;15373:19;15381:10;15373:7;:19::i;:::-;15344:417;;;15601:17;;:22;:49;;;;-1:-1:-1;;;;;;15627:18:0;;;:23;15601:49;15597:121;;;15678:24;;-1:-1:-1;;;15678:24:0;;-1:-1:-1;;;;;200:32:1;;15678:24:0;;;182:51:1;155:18;;15678:24:0;14:225:1;15597:121:0;-1:-1:-1;15739:10:0;15344:417;15171:597;;;;;:::o;45930:1705::-;46057:12;46153;46150:1384;;;46287:12;46284:1;46280:20;46266:12;46262:39;46413:12;46551:968;46778:20;;46769:30;;;46766:1;46762:38;47067:22;;;47132:2;47118:17;;;47111:47;47284:2;47281:1;47271:16;;47358:15;47474;;;46551:968;47464:36;46555:2;;46150:1384;-1:-1:-1;47561:14:0;;45930:1705;-1:-1:-1;;45930:1705:0:o;16321:528::-;16454:17;;:21;16450:392;;16686:10;16680:17;16743:15;16730:10;16726:2;16722:19;16715:44;16450:392;16813:17;;-1:-1:-1;;;16813:17:0;;;;;;;;;;;16450:392;16321:528;:::o;244:131:1:-;-1:-1:-1;;;;;319:31:1;;309:42;;299:70;;365:1;362;355:12;380:315;448:6;456;509:2;497:9;488:7;484:23;480:32;477:52;;;525:1;522;515:12;477:52;564:9;551:23;583:31;608:5;583:31;:::i;:::-;633:5;685:2;670:18;;;;657:32;;-1:-1:-1;;;380:315:1:o;700:386::-;782:8;792:6;846:3;839:4;831:6;827:17;823:27;813:55;;864:1;861;854:12;813:55;-1:-1:-1;887:20:1;;-1:-1:-1;;;;;919:30:1;;916:50;;;962:1;959;952:12;916:50;999:4;991:6;987:17;975:29;;1059:3;1052:4;1042:6;1039:1;1035:14;1027:6;1023:27;1019:38;1016:47;1013:67;;;1076:1;1073;1066:12;1013:67;700:386;;;;;:::o;1091:1853::-;1359:6;1367;1375;1383;1391;1399;1407;1415;1423;1431;1484:3;1472:9;1463:7;1459:23;1455:33;1452:53;;;1501:1;1498;1491:12;1452:53;1541:9;1528:23;-1:-1:-1;;;;;1611:2:1;1603:6;1600:14;1597:34;;;1627:1;1624;1617:12;1597:34;1666:89;1747:7;1738:6;1727:9;1723:22;1666:89;:::i;:::-;1774:8;;-1:-1:-1;1640:115:1;-1:-1:-1;1862:2:1;1847:18;;1834:32;;-1:-1:-1;1878:16:1;;;1875:36;;;1907:1;1904;1897:12;1875:36;1946:91;2029:7;2018:8;2007:9;2003:24;1946:91;:::i;:::-;2056:8;;-1:-1:-1;1920:117:1;-1:-1:-1;2144:2:1;2129:18;;2116:32;;-1:-1:-1;2160:16:1;;;2157:36;;;2189:1;2186;2179:12;2157:36;2228:91;2311:7;2300:8;2289:9;2285:24;2228:91;:::i;:::-;2338:8;;-1:-1:-1;2202:117:1;-1:-1:-1;2426:2:1;2411:18;;2398:32;;-1:-1:-1;2442:16:1;;;2439:36;;;2471:1;2468;2461:12;2439:36;2510:91;2593:7;2582:8;2571:9;2567:24;2510:91;:::i;:::-;2620:8;;-1:-1:-1;2484:117:1;-1:-1:-1;2708:3:1;2693:19;;2680:33;;-1:-1:-1;2725:16:1;;;2722:36;;;2754:1;2751;2744:12;2722:36;;2793:91;2876:7;2865:8;2854:9;2850:24;2793:91;:::i;:::-;2767:117;;2903:8;2893:18;;;2930:8;2920:18;;;1091:1853;;;;;;;;;;;;;:::o;2949:347::-;3000:8;3010:6;3064:3;3057:4;3049:6;3045:17;3041:27;3031:55;;3082:1;3079;3072:12;3031:55;-1:-1:-1;3105:20:1;;-1:-1:-1;;;;;3137:30:1;;3134:50;;;3180:1;3177;3170:12;3134:50;3217:4;3209:6;3205:17;3193:29;;3269:3;3262:4;3253:6;3245;3241:19;3237:30;3234:39;3231:59;;;3286:1;3283;3276:12;3301:1234;3452:6;3460;3468;3476;3484;3492;3500;3553:3;3541:9;3532:7;3528:23;3524:33;3521:53;;;3570:1;3567;3560:12;3521:53;3609:9;3596:23;3628:31;3653:5;3628:31;:::i;:::-;3678:5;-1:-1:-1;3734:2:1;3719:18;;3706:32;-1:-1:-1;;;;;3787:14:1;;;3784:34;;;3814:1;3811;3804:12;3784:34;3853:89;3934:7;3925:6;3914:9;3910:22;3853:89;:::i;:::-;3961:8;;-1:-1:-1;3827:115:1;-1:-1:-1;4049:2:1;4034:18;;4021:32;;-1:-1:-1;4065:16:1;;;4062:36;;;4094:1;4091;4084:12;4062:36;4133:91;4216:7;4205:8;4194:9;4190:24;4133:91;:::i;:::-;4243:8;;-1:-1:-1;4107:117:1;-1:-1:-1;4331:2:1;4316:18;;4303:32;;-1:-1:-1;4347:16:1;;;4344:36;;;4376:1;4373;4366:12;4344:36;;4415:60;4467:7;4456:8;4445:9;4441:24;4415:60;:::i;:::-;3301:1234;;;;-1:-1:-1;3301:1234:1;;-1:-1:-1;3301:1234:1;;;;4389:86;;-1:-1:-1;;;3301:1234:1:o;4540:247::-;4599:6;4652:2;4640:9;4631:7;4627:23;4623:32;4620:52;;;4668:1;4665;4658:12;4620:52;4707:9;4694:23;4726:31;4751:5;4726:31;:::i;5870:1433::-;6048:6;6056;6064;6072;6080;6088;6096;6104;6157:3;6145:9;6136:7;6132:23;6128:33;6125:53;;;6174:1;6171;6164:12;6125:53;6214:9;6201:23;-1:-1:-1;;;;;6284:2:1;6276:6;6273:14;6270:34;;;6300:1;6297;6290:12;6270:34;6339:89;6420:7;6411:6;6400:9;6396:22;6339:89;:::i;:::-;6447:8;;-1:-1:-1;6313:115:1;-1:-1:-1;6535:2:1;6520:18;;6507:32;;-1:-1:-1;6551:16:1;;;6548:36;;;6580:1;6577;6570:12;6548:36;6619:91;6702:7;6691:8;6680:9;6676:24;6619:91;:::i;:::-;6729:8;;-1:-1:-1;6593:117:1;-1:-1:-1;6817:2:1;6802:18;;6789:32;;-1:-1:-1;6833:16:1;;;6830:36;;;6862:1;6859;6852:12;6830:36;6901:91;6984:7;6973:8;6962:9;6958:24;6901:91;:::i;:::-;7011:8;;-1:-1:-1;6875:117:1;-1:-1:-1;7099:2:1;7084:18;;7071:32;;-1:-1:-1;7115:16:1;;;7112:36;;;7144:1;7141;7134:12;7112:36;;7183:60;7235:7;7224:8;7213:9;7209:24;7183:60;:::i;:::-;5870:1433;;;;-1:-1:-1;5870:1433:1;;-1:-1:-1;5870:1433:1;;;;;;7262:8;-1:-1:-1;;;5870:1433:1:o;7544:336::-;7746:2;7728:21;;;7785:2;7765:18;;;7758:30;-1:-1:-1;;;7819:2:1;7804:18;;7797:42;7871:2;7856:18;;7544:336::o;8138:184::-;8208:6;8261:2;8249:9;8240:7;8236:23;8232:32;8229:52;;;8277:1;8274;8267:12;8229:52;-1:-1:-1;8300:16:1;;8138:184;-1:-1:-1;8138:184:1:o;8327:127::-;8388:10;8383:3;8379:20;8376:1;8369:31;8419:4;8416:1;8409:15;8443:4;8440:1;8433:15;8459:545;8552:4;8558:6;8618:11;8605:25;8712:2;8708:7;8697:8;8681:14;8677:29;8673:43;8653:18;8649:68;8639:96;;8731:1;8728;8721:12;8639:96;8758:33;;8810:20;;;-1:-1:-1;;;;;;8842:30:1;;8839:50;;;8885:1;8882;8875:12;8839:50;8918:4;8906:17;;-1:-1:-1;8969:1:1;8965:14;;;8949;8945:35;8935:46;;8932:66;;;8994:1;8991;8984:12;9009:521;9086:4;9092:6;9152:11;9139:25;9246:2;9242:7;9231:8;9215:14;9211:29;9207:43;9187:18;9183:68;9173:96;;9265:1;9262;9255:12;9173:96;9292:33;;9344:20;;;-1:-1:-1;;;;;;9376:30:1;;9373:50;;;9419:1;9416;9409:12;9373:50;9452:4;9440:17;;-1:-1:-1;9483:14:1;9479:27;;;9469:38;;9466:58;;;9520:1;9517;9510:12;9535:266;9623:6;9618:3;9611:19;9675:6;9668:5;9661:4;9656:3;9652:14;9639:43;-1:-1:-1;9727:1:1;9702:16;;;9720:4;9698:27;;;9691:38;;;;9783:2;9762:15;;;-1:-1:-1;;9758:29:1;9749:39;;;9745:50;;9535:266::o;9806:412::-;-1:-1:-1;;;;;10019:32:1;;10001:51;;10088:2;10083;10068:18;;10061:30;;;-1:-1:-1;;10108:61:1;;10150:18;;10142:6;10134;10108:61;:::i;:::-;10100:69;;10205:6;10200:2;10189:9;10185:18;10178:34;9806:412;;;;;;;:::o;10223:127::-;10284:10;10279:3;10275:20;10272:1;10265:31;10315:4;10312:1;10305:15;10339:4;10336:1;10329:15;10355:275;10426:2;10420:9;10491:2;10472:13;;-1:-1:-1;;10468:27:1;10456:40;;-1:-1:-1;;;;;10511:34:1;;10547:22;;;10508:62;10505:88;;;10573:18;;:::i;:::-;10609:2;10602:22;10355:275;;-1:-1:-1;10355:275:1:o;10635:186::-;10683:4;-1:-1:-1;;;;;10708:6:1;10705:30;10702:56;;;10738:18;;:::i;:::-;-1:-1:-1;10804:2:1;10783:15;-1:-1:-1;;10779:29:1;10810:4;10775:40;;10635:186::o;10826:250::-;10911:1;10921:113;10935:6;10932:1;10929:13;10921:113;;;11011:11;;;11005:18;10992:11;;;10985:39;10957:2;10950:10;10921:113;;;-1:-1:-1;;11068:1:1;11050:16;;11043:27;10826:250::o;11081:441::-;11134:5;11187:3;11180:4;11172:6;11168:17;11164:27;11154:55;;11205:1;11202;11195:12;11154:55;11234:6;11228:13;11265:48;11281:31;11309:2;11281:31;:::i;:::-;11265:48;:::i;:::-;11338:2;11329:7;11322:19;11384:3;11377:4;11372:2;11364:6;11360:15;11356:26;11353:35;11350:55;;;11401:1;11398;11391:12;11350:55;11414:77;11488:2;11481:4;11472:7;11468:18;11461:4;11453:6;11449:17;11414:77;:::i;:::-;11509:7;11081:441;-1:-1:-1;;;;11081:441:1:o;11527:335::-;11606:6;11659:2;11647:9;11638:7;11634:23;11630:32;11627:52;;;11675:1;11672;11665:12;11627:52;11708:9;11702:16;-1:-1:-1;;;;;11733:6:1;11730:30;11727:50;;;11773:1;11770;11763:12;11727:50;11796:60;11848:7;11839:6;11828:9;11824:22;11796:60;:::i;11867:127::-;11928:10;11923:3;11919:20;11916:1;11909:31;11959:4;11956:1;11949:15;11983:4;11980:1;11973:15;11999:135;12038:3;12059:17;;;12056:43;;12079:18;;:::i;:::-;-1:-1:-1;12126:1:1;12115:13;;11999:135::o;12321:271::-;12504:6;12496;12491:3;12478:33;12460:3;12530:16;;12555:13;;;12530:16;12321:271;-1:-1:-1;12321:271:1:o;12597:522::-;12697:6;12692:3;12685:19;12667:3;12723:4;12752:2;12747:3;12743:12;12736:19;;12778:5;12801:1;12811:283;12825:6;12822:1;12819:13;12811:283;;;12902:6;12889:20;12922:33;12947:7;12922:33;:::i;:::-;-1:-1:-1;;;;;12980:33:1;12968:46;;13034:12;;;;13069:15;;;;13010:1;12840:9;12811:283;;;-1:-1:-1;13110:3:1;;12597:522;-1:-1:-1;;;;;12597:522:1:o;13124:951::-;-1:-1:-1;;;;;13485:32:1;;13467:51;;13554:3;13549:2;13534:18;;13527:31;;;-1:-1:-1;;13581:74:1;;13635:19;;13627:6;13619;13581:74;:::i;:::-;13691:22;;;13686:2;13671:18;;13664:50;13723:22;;;-1:-1:-1;;;;;13757:31:1;;13754:51;;;13801:1;13798;13791:12;13754:51;13835:6;13832:1;13828:14;13889:6;13881;13876:2;13868:6;13864:15;13851:45;13915:19;13974:18;;;13994:2;13970:27;;;13965:2;13950:18;;13943:55;14015:54;;14057:11;;14049:6;14041;14015:54;:::i;:::-;14007:62;13124:951;-1:-1:-1;;;;;;;;;;13124:951:1:o;14080:400::-;-1:-1:-1;;;;;14336:15:1;;;14318:34;;14388:15;;;;14383:2;14368:18;;14361:43;-1:-1:-1;;;;;;14440:33:1;;;14435:2;14420:18;;14413:61;14268:2;14253:18;;14080:400::o;14485:277::-;14552:6;14605:2;14593:9;14584:7;14580:23;14576:32;14573:52;;;14621:1;14618;14611:12;14573:52;14653:9;14647:16;14706:5;14699:13;14692:21;14685:5;14682:32;14672:60;;14728:1;14725;14718:12;14767:193;14837:4;-1:-1:-1;;;;;14862:6:1;14859:30;14856:56;;;14892:18;;:::i;:::-;-1:-1:-1;14937:1:1;14933:14;14949:4;14929:25;;14767:193::o;14965:1725::-;15029:5;15082:3;15075:4;15067:6;15063:17;15059:27;15049:55;;15100:1;15097;15090:12;15049:55;15136:6;15123:20;15162:4;15186:70;15202:53;15252:2;15202:53;:::i;15186:70::-;15290:15;;;15352:1;15392:11;;;15380:24;;15376:33;;;15321:12;;;;15278:3;15421:15;;;15418:35;;;15449:1;15446;15439:12;15418:35;15485:2;15477:6;15473:15;15497:1164;15513:6;15508:3;15505:15;15497:1164;;;15599:3;15586:17;-1:-1:-1;;;;;15622:11:1;15619:35;15616:125;;;15695:1;15724:2;15720;15713:14;15616:125;15764:24;;15823:2;15815:11;;15811:21;-1:-1:-1;15801:119:1;;15874:1;15903:2;15899;15892:14;15801:119;15964:2;15960;15956:11;15943:25;15991:2;16019:70;16035:53;16085:2;16035:53;:::i;16019:70::-;16133:17;;;16227:11;;;16219:20;;16215:29;;;16172:14;;;;16260:17;;;16257:107;;;16318:1;16347:2;16343;16336:14;16257:107;16390:11;;;;16414:174;16432:8;16425:5;16422:19;16414:174;;;16514:19;;16500:34;;16453:14;;;;16560;;;;16414:174;;;16601:18;;-1:-1:-1;;;16639:12:1;;;;-1:-1:-1;15530:12:1;;15497:1164;;;-1:-1:-1;16679:5:1;;14965:1725;-1:-1:-1;;;;;;;14965:1725:1:o;16695:747::-;16749:5;16802:3;16795:4;16787:6;16783:17;16779:27;16769:55;;16820:1;16817;16810:12;16769:55;16856:6;16843:20;16882:4;16906:70;16922:53;16972:2;16922:53;:::i;16906:70::-;17010:15;;;17096:1;17092:10;;;;17080:23;;17076:32;;;17041:12;;;;17120:15;;;17117:35;;;17148:1;17145;17138:12;17117:35;17184:2;17176:6;17172:15;17196:217;17212:6;17207:3;17204:15;17196:217;;;17292:3;17279:17;17309:31;17334:5;17309:31;:::i;:::-;17353:18;;17391:12;;;;17229;;17196:217;;;-1:-1:-1;17431:5:1;16695:747;-1:-1:-1;;;;;;16695:747:1:o;17447:1448::-;17499:5;17552:3;17545:4;17537:6;17533:17;17529:27;17519:55;;17570:1;17567;17560:12;17519:55;17606:6;17593:20;17632:4;17656:70;17672:53;17722:2;17672:53;:::i;17656:70::-;17760:15;;;17846:1;17842:10;;;;17830:23;;17826:32;;;17791:12;;;;17870:15;;;17867:35;;;17898:1;17895;17888:12;17867:35;17934:2;17926:6;17922:15;17946:920;17962:6;17957:3;17954:15;17946:920;;;18048:3;18035:17;-1:-1:-1;;;;;18071:11:1;18068:35;18065:125;;;18144:1;18173:2;18169;18162:14;18065:125;18213:24;;18272:2;18264:11;;18260:21;-1:-1:-1;18250:119:1;;18323:1;18352:2;18348;18341:14;18250:119;18413:2;18409;18405:11;18392:25;18440:2;18470:48;18486:31;18514:2;18486:31;:::i;18470:48::-;18547:2;18538:7;18531:19;18591:3;18586:2;18581;18577;18573:11;18569:20;18566:29;18563:119;;;18636:1;18665:2;18661;18654:14;18563:119;18739:2;18734;18730;18726:11;18721:2;18712:7;18708:16;18695:47;18789:1;18766:16;;;18762:25;;18755:36;;;;-1:-1:-1;18804:20:1;;-1:-1:-1;18844:12:1;;;;17979;;17946:920;;18900:672;18954:5;19007:3;19000:4;18992:6;18988:17;18984:27;18974:55;;19025:1;19022;19015:12;18974:55;19061:6;19048:20;19087:4;19111:70;19127:53;19177:2;19127:53;:::i;19111:70::-;19215:15;;;19301:1;19297:10;;;;19285:23;;19281:32;;;19246:12;;;;19325:15;;;19322:35;;;19353:1;19350;19343:12;19322:35;19389:2;19381:6;19377:15;19401:142;19417:6;19412:3;19409:15;19401:142;;;19483:17;;19471:30;;19521:12;;;;19434;;19401:142;;19577:1317;19831:6;19839;19847;19855;19863;19916:3;19904:9;19895:7;19891:23;19887:33;19884:53;;;19933:1;19930;19923:12;19884:53;19973:9;19960:23;-1:-1:-1;;;;;20043:2:1;20035:6;20032:14;20029:34;;;20059:1;20056;20049:12;20029:34;20082:71;20145:7;20136:6;20125:9;20121:22;20082:71;:::i;:::-;20072:81;;20206:2;20195:9;20191:18;20178:32;20162:48;;20235:2;20225:8;20222:16;20219:36;;;20251:1;20248;20241:12;20219:36;20274:63;20329:7;20318:8;20307:9;20303:24;20274:63;:::i;:::-;20264:73;;20390:2;20379:9;20375:18;20362:32;20346:48;;20419:2;20409:8;20406:16;20403:36;;;20435:1;20432;20425:12;20403:36;20458:63;20513:7;20502:8;20491:9;20487:24;20458:63;:::i;:::-;20448:73;;20574:2;20563:9;20559:18;20546:32;20530:48;;20603:2;20593:8;20590:16;20587:36;;;20619:1;20616;20609:12;20587:36;20642:61;20695:7;20684:8;20673:9;20669:24;20642:61;:::i;:::-;20632:71;;20756:3;20745:9;20741:19;20728:33;20712:49;;20786:2;20776:8;20773:16;20770:36;;;20802:1;20799;20792:12;20770:36;;20825:63;20880:7;20869:8;20858:9;20854:24;20825:63;:::i;:::-;20815:73;;;19577:1317;;;;;;;;:::o;20899:461::-;20952:3;20990:5;20984:12;21017:6;21012:3;21005:19;21043:4;21072:2;21067:3;21063:12;21056:19;;21109:2;21102:5;21098:14;21130:1;21140:195;21154:6;21151:1;21148:13;21140:195;;;21219:13;;-1:-1:-1;;;;;21215:39:1;21203:52;;21275:12;;;;21310:15;;;;21251:1;21169:9;21140:195;;21365:822;21416:3;21454:5;21448:12;21481:6;21476:3;21469:19;21507:4;21548:2;21543:3;21539:12;21573:11;21600;21593:18;;21650:6;21647:1;21643:14;21636:5;21632:26;21620:38;;21692:2;21685:5;21681:14;21713:1;21723:438;21737:6;21734:1;21731:13;21723:438;;;21808:5;21802:4;21798:16;21793:3;21786:29;21844:6;21838:13;21886:2;21880:9;21915:8;21909:4;21902:22;21937:72;22000:8;21995:2;21989:4;21985:13;21980:2;21976;21972:11;21937:72;:::i;:::-;22139:12;;;;22071:2;22048:17;-1:-1:-1;;22044:31:1;22034:42;;;;22030:51;;;-1:-1:-1;22104:15:1;;;;21759:1;21752:9;21723:438;;;-1:-1:-1;22177:4:1;;21365:822;-1:-1:-1;;;;;;;21365:822:1:o;22192:435::-;22245:3;22283:5;22277:12;22310:6;22305:3;22298:19;22336:4;22365:2;22360:3;22356:12;22349:19;;22402:2;22395:5;22391:14;22423:1;22433:169;22447:6;22444:1;22441:13;22433:169;;;22508:13;;22496:26;;22542:12;;;;22577:15;;;;22469:1;22462:9;22433:169;;22632:2103;23154:4;23202:3;23191:9;23187:19;23233:3;23222:9;23215:22;23257:6;23292;23286:13;23323:6;23315;23308:22;23361:3;23350:9;23346:19;23339:26;;23424:3;23414:6;23411:1;23407:14;23396:9;23392:30;23388:40;23374:54;;23447:4;23486:2;23478:6;23474:15;23507:1;23528;23538:694;23554:6;23549:3;23546:15;23538:694;;;23623:22;;;-1:-1:-1;;23619:37:1;23607:50;;23680:13;;23754:9;;23776:24;;;23866:11;;;;23822:15;;;;23901:1;23915:209;23931:8;23926:3;23923:17;23915:209;;;24008:15;;23994:30;;24093:17;;;;24050:14;;;;23959:1;23950:11;23915:209;;;-1:-1:-1;24147:5:1;;-1:-1:-1;;;24210:12:1;;;;24175:15;;;;23580:1;23571:11;23538:694;;;23542:3;;;24280:9;24272:6;24268:22;24263:2;24252:9;24248:18;24241:50;;;;24314:44;24351:6;24343;24314:44;:::i;:::-;24300:58;;24406:9;24398:6;24394:22;24389:2;24378:9;24374:18;24367:50;24440:44;24477:6;24469;24440:44;:::i;:::-;24426:58;;24532:9;24524:6;24520:22;24515:2;24504:9;24500:18;24493:50;24566:42;24601:6;24593;24566:42;:::i;:::-;24552:56;;24657:9;24649:6;24645:22;24639:3;24628:9;24624:19;24617:51;24685:44;24722:6;24714;24685:44;:::i;:::-;24677:52;22632:2103;-1:-1:-1;;;;;;;;22632:2103:1:o;24740:125::-;24805:9;;;24826:10;;;24823:36;;;24839:18;;:::i;25149:712::-;25512:2;25501:9;25494:21;25475:4;25538:73;25607:2;25596:9;25592:18;25584:6;25576;25538:73;:::i;:::-;25659:9;25651:6;25647:22;25642:2;25631:9;25627:18;25620:50;25693:42;25728:6;25720;25693:42;:::i;:::-;25679:56;;25783:9;25775:6;25771:22;25766:2;25755:9;25751:18;25744:50;25811:44;25848:6;25840;25811:44;:::i;:::-;25803:52;25149:712;-1:-1:-1;;;;;;;25149:712:1:o;25866:1142::-;25970:6;26001:2;26044;26032:9;26023:7;26019:23;26015:32;26012:52;;;26060:1;26057;26050:12;26012:52;26093:9;26087:16;-1:-1:-1;;;;;26163:2:1;26155:6;26152:14;26149:34;;;26179:1;26176;26169:12;26149:34;26217:6;26206:9;26202:22;26192:32;;26262:7;26255:4;26251:2;26247:13;26243:27;26233:55;;26284:1;26281;26274:12;26233:55;26313:2;26307:9;26336:70;26352:53;26402:2;26352:53;:::i;26336:70::-;26440:15;;;26522:1;26518:10;;;;26510:19;;26506:28;;;26471:12;;;;26546:19;;;26543:39;;;26578:1;26575;26568:12;26543:39;26610:2;26606;26602:11;26622:356;26638:6;26633:3;26630:15;26622:356;;;26717:3;26711:10;26753:2;26740:11;26737:19;26734:109;;;26797:1;26826:2;26822;26815:14;26734:109;26868:67;26927:7;26922:2;26908:11;26904:2;26900:20;26896:29;26868:67;:::i;:::-;26856:80;;-1:-1:-1;26956:12:1;;;;26655;;26622:356;;;-1:-1:-1;26997:5:1;25866:1142;-1:-1:-1;;;;;;;;25866:1142:1:o;27013:428::-;27170:3;27208:6;27202:13;27224:66;27283:6;27278:3;27271:4;27263:6;27259:17;27224:66;:::i;:::-;27359:2;27355:15;;;;-1:-1:-1;;;;;;27351:53:1;27312:16;;;;27337:68;;;27432:2;27421:14;;27013:428;-1:-1:-1;;27013:428:1:o;27446:323::-;-1:-1:-1;;;;;;27566:19:1;;27642:11;;;;27673:1;27665:10;;27662:101;;;27734:1;27730:11;;;;27727:1;27723:19;27719:28;;;27711:37;27707:46;;;;27446:323;-1:-1:-1;;27446:323:1:o;28118:287::-;28247:3;28285:6;28279:13;28301:66;28360:6;28355:3;28348:4;28340:6;28336:17;28301:66;:::i;:::-;28383:16;;;;;28118:287;-1:-1:-1;;28118:287:1:o;28410:128::-;28477:9;;;28498:11;;;28495:37;;;28512:18;;:::i;28543:331::-;28648:9;28659;28701:8;28689:10;28686:24;28683:44;;;28723:1;28720;28713:12;28683:44;28752:6;28742:8;28739:20;28736:40;;;28772:1;28769;28762:12;28736:40;-1:-1:-1;;28798:23:1;;;28843:25;;;;;-1:-1:-1;28543:331:1:o;28879:255::-;28999:19;;29038:2;29030:11;;29027:101;;;-1:-1:-1;;29099:2:1;29095:12;;;29092:1;29088:20;29084:33;29073:45;28879:255;;;;:::o;29139:337::-;-1:-1:-1;;;;;;29260:19:1;;29347:11;;;;29378:2;29370:11;;29367:103;;;29440:2;29436:12;;;;29433:1;29429:20;29425:29;;;29417:38;29413:47;;;;29139:337;-1:-1:-1;;29139:337:1:o;29481:687::-;-1:-1:-1;;;;;;29802:2:1;29798:15;;;29794:24;;29782:37;;29853:15;;;29849:24;29844:2;29835:12;;29828:46;29920:14;;29913:22;29908:3;29904:32;29899:2;29890:12;;29883:54;-1:-1:-1;;;;;;29967:33:1;;29962:2;29953:12;;29946:55;30024:13;;-1:-1:-1;;30046:75:1;30024:13;30109:2;30100:12;;30093:4;30081:17;;30046:75;:::i;:::-;30141:16;;;;30159:2;30137:25;;29481:687;-1:-1:-1;;;;;;29481:687:1:o
Swarm Source
ipfs://d4085813f4c1efdd3ee505e462b8bda5c8366371f4670da97da8021b5ac2ff9a
Loading...
Loading
Loading...
Loading

Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
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.