ERC-20
Overview
Max Total Supply
462,384.294951 scUSD
Holders
102
Market
Price
-
Onchain Market Cap
-
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 6 Decimals)
Balance
1.797294 scUSDValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
BoringVault
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.21; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol"; import {SafeTransferLib} from "@solmate/utils/SafeTransferLib.sol"; import {ERC20} from "@solmate/tokens/ERC20.sol"; import {BeforeTransferHook} from "src/interfaces/BeforeTransferHook.sol"; import {Auth, Authority} from "@solmate/auth/Auth.sol"; 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 {} }
// SPDX-License-Identifier: MIT // 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(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.20; import {IERC721Receiver} from "../IERC721Receiver.sol"; /** * @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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.20; import {IERC165, ERC165} from "../../../utils/introspection/ERC165.sol"; import {IERC1155Receiver} from "../IERC1155Receiver.sol"; /** * @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; } }
// SPDX-License-Identifier: AGPL-3.0-only 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)) } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @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"); } }
// SPDX-License-Identifier: AGPL-3.0-only 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); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.21; interface BeforeTransferHook { function beforeTransfer(address from, address to, address operator) external view; }
// SPDX-License-Identifier: AGPL-3.0-only 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); }
// SPDX-License-Identifier: MIT // 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @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); }
// SPDX-License-Identifier: MIT // 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); }
{ "remappings": [ "@solmate/=lib/solmate/src/", "@forge-std/=lib/forge-std/src/", "@ds-test/=lib/forge-std/lib/ds-test/src/", "ds-test/=lib/forge-std/lib/ds-test/src/", "@openzeppelin/=lib/openzeppelin-contracts/", "@ccip/=lib/ccip/", "@oapp-auth/=lib/OAppAuth/src/", "@devtools-oapp-evm/=lib/OAppAuth/lib/devtools/packages/oapp-evm/contracts/oapp/", "@layerzerolabs/lz-evm-messagelib-v2/=lib/OAppAuth/node_modules/@layerzerolabs/lz-evm-messagelib-v2/", "@layerzerolabs/lz-evm-protocol-v2/=lib/OAppAuth/lib/LayerZero-V2/packages/layerzero-v2/evm/protocol/", "@layerzerolabs/oapp-evm/=lib/OAppAuth/lib/devtools/packages/oapp-evm/", "@lz-oapp-evm/=lib/OAppAuth/lib/LayerZero-V2/packages/layerzero-v2/evm/oapp/contracts/oapp/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@sbu/=lib/OAppAuth/lib/solidity-bytes-utils/", "LayerZero-V2/=lib/OAppAuth/lib/", "OAppAuth/=lib/OAppAuth/", "ccip/=lib/ccip/contracts/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "halmos-cheatcodes/=lib/OAppAuth/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solidity-bytes-utils/=lib/OAppAuth/node_modules/solidity-bytes-utils/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"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":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Enter","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Exit","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":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract Authority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"contract ERC20","name":"asset","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"shareAmount","type":"uint256"}],"name":"enter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"contract ERC20","name":"asset","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"shareAmount","type":"uint256"}],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"hook","outputs":[{"internalType":"contract BeforeTransferHook","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"manage","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"manage","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_hook","type":"address"}],"name":"setBeforeTransferHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e06040523480156200001157600080fd5b506040516200233738038062002337833981016040819052620000349162000270565b83600084848483620000478482620003a3565b506001620000568382620003a3565b5060ff81166080524660a0526200006c6200010f565b60c0525050600680546001600160a01b038086166001600160a01b03199283168117909355600780549186169190921617905560405190915033907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a3505050505050620004ed565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516200014391906200046f565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001d357600080fd5b81516001600160401b0380821115620001f057620001f0620001ab565b604051601f8301601f19908116603f011681019082821181831017156200021b576200021b620001ab565b816040528381526020925086838588010111156200023857600080fd5b600091505b838210156200025c57858201830151818301840152908201906200023d565b600093810190920192909252949350505050565b600080600080608085870312156200028757600080fd5b84516001600160a01b03811681146200029f57600080fd5b60208601519094506001600160401b0380821115620002bd57600080fd5b620002cb88838901620001c1565b94506040870151915080821115620002e257600080fd5b50620002f187828801620001c1565b925050606085015160ff811681146200030957600080fd5b939692955090935050565b600181811c908216806200032957607f821691505b6020821081036200034a57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039e57600081815260208120601f850160051c81016020861015620003795750805b601f850160051c820191505b818110156200039a5782815560010162000385565b5050505b505050565b81516001600160401b03811115620003bf57620003bf620001ab565b620003d781620003d0845462000314565b8462000350565b602080601f8311600181146200040f5760008415620003f65750858301515b600019600386901b1c1916600185901b1785556200039a565b600085815260208120601f198616915b8281101562000440578886015182559484019460019091019084016200041f565b50858210156200045f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008083546200047f8162000314565b600182811680156200049a5760018114620004b057620004e1565b60ff1984168752821515830287019450620004e1565b8760005260208060002060005b85811015620004d85781548a820152908401908201620004bd565b50505082870194505b50929695505050505050565b60805160a05160c051611e1a6200051d600039600061095901526000610924015260006102f10152611e1a6000f3fe6080604052600436106101855760003560e01c80637ecebe00116100d1578063bc197c811161008a578063dd62ed3e11610064578063dd62ed3e146104ed578063f23a6e6114610525578063f2fde38b14610551578063f6e715d01461057157600080fd5b8063bc197c8114610481578063bf7e214f146104ad578063d505accf146104cd57600080fd5b80637ecebe00146103a75780637f5a7c7b146103d45780638929565f1461040c5780638da5cb5b1461042c57806395d89b411461044c578063a9059cbb1461046157600080fd5b8063224d87031161013e5780633644e515116101185780633644e5151461032557806339d6ba321461033a57806370a082311461035a5780637a9e5e4b1461038757600080fd5b8063224d87031461029257806323b872dd146102bf578063313ce567146102df57600080fd5b806301ffc9a71461019157806306fdde03146101c6578063095ea7b3146101e8578063150b7a021461020857806318160ddd1461024c57806318457e611461027057600080fd5b3661018c57005b600080fd5b34801561019d57600080fd5b506101b16101ac3660046114e4565b610591565b60405190151581526020015b60405180910390f35b3480156101d257600080fd5b506101db6105c8565b6040516101bd919061155e565b3480156101f457600080fd5b506101b1610203366004611586565b610656565b34801561021457600080fd5b50610233610223366004611669565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016101bd565b34801561025857600080fd5b5061026260025481565b6040519081526020016101bd565b34801561027c57600080fd5b5061029061028b3660046116d5565b6106c2565b005b34801561029e57600080fd5b506102b26102ad36600461177c565b610788565b6040516101bd9190611816565b3480156102cb57600080fd5b506101b16102da366004611878565b6108ff565b3480156102eb57600080fd5b506103137f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016101bd565b34801561033157600080fd5b50610262610920565b34801561034657600080fd5b506102906103553660046116d5565b61097b565b34801561036657600080fd5b506102626103753660046118b9565b60036020526000908152604090205481565b34801561039357600080fd5b506102906103a23660046118b9565b610a2a565b3480156103b357600080fd5b506102626103c23660046118b9565b60056020526000908152604090205481565b3480156103e057600080fd5b506008546103f4906001600160a01b031681565b6040516001600160a01b0390911681526020016101bd565b34801561041857600080fd5b506102906104273660046118b9565b610b14565b34801561043857600080fd5b506006546103f4906001600160a01b031681565b34801561045857600080fd5b506101db610b68565b34801561046d57600080fd5b506101b161047c366004611586565b610b75565b34801561048d57600080fd5b5061023361049c366004611956565b63bc197c8160e01b95945050505050565b3480156104b957600080fd5b506007546103f4906001600160a01b031681565b3480156104d957600080fd5b506102906104e8366004611a04565b610b8b565b3480156104f957600080fd5b50610262610508366004611a7b565b600460209081526000928352604080842090915290825290205481565b34801561053157600080fd5b50610233610540366004611ab4565b63f23a6e6160e01b95945050505050565b34801561055d57600080fd5b5061029061056c3660046118b9565b610dcf565b34801561057d57600080fd5b506101db61058c366004611b1d565b610e4d565b60006001600160e01b03198216630271189760e51b14806105c257506301ffc9a760e01b6001600160e01b03198316145b92915050565b600080546105d590611ba8565b80601f016020809104026020016040519081016040528092919081815260200182805461060190611ba8565b801561064e5780601f106106235761010080835404028352916020019161064e565b820191906000526020600020905b81548152906001019060200180831161063157829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106b19086815260200190565b60405180910390a350600192915050565b6106d8336000356001600160e01b031916610ed5565b6106fd5760405162461bcd60e51b81526004016106f490611be2565b60405180910390fd5b6107078282610f7f565b8215610721576107216001600160a01b0385168685610fe9565b816001600160a01b0316846001600160a01b0316866001600160a01b03167fe0c82280a1164680e0cf43be7db4c4c9f985423623ad7a544fb76c772bdc60438685604051610779929190918252602082015260400190565b60405180910390a45050505050565b60606107a0336000356001600160e01b031916610ed5565b6107bc5760405162461bcd60e51b81526004016106f490611be2565b858067ffffffffffffffff8111156107d6576107d66115b2565b60405190808252806020026020018201604052801561080957816020015b60608152602001906001900390816107f45790505b50915060005b818110156108f3576108c587878381811061082c5761082c611c08565b905060200281019061083e9190611c1e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525089925088915085905081811061088757610887611c08565b905060200201358b8b858181106108a0576108a0611c08565b90506020020160208101906108b591906118b9565b6001600160a01b03169190611070565b8382815181106108d7576108d7611c08565b6020026020010181905250806108ec90611c7b565b905061080f565b50509695505050505050565b600061090b848461110d565b61091684848461118e565b90505b9392505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146109565761095161126e565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b610991336000356001600160e01b031916610ed5565b6109ad5760405162461bcd60e51b81526004016106f490611be2565b82156109c8576109c86001600160a01b038516863086611308565b6109d282826113a4565b816001600160a01b0316846001600160a01b0316866001600160a01b03167fea00f88768a86184a6e515238a549c171769fe7460a011d6fd0bcd48ca078ea48685604051610779929190918252602082015260400190565b6006546001600160a01b0316331480610abf575060075460405163b700961360e01b81526001600160a01b039091169063b700961390610a7e90339030906001600160e01b03196000351690600401611c94565b602060405180830381865afa158015610a9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abf9190611cc1565b610ac857600080fd5b600780546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b610b2a336000356001600160e01b031916610ed5565b610b465760405162461bcd60e51b81526004016106f490611be2565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b600180546105d590611ba8565b6000610b81338461110d565b61091983836113f6565b42841015610bdb5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016106f4565b60006001610be7610920565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610cf3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610d295750876001600160a01b0316816001600160a01b0316145b610d665760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b60448201526064016106f4565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b610de5336000356001600160e01b031916610ed5565b610e015760405162461bcd60e51b81526004016106f490611be2565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6060610e65336000356001600160e01b031916610ed5565b610e815760405162461bcd60e51b81526004016106f490611be2565b610ecc84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050506001600160a01b03881691905084611070565b95945050505050565b6007546000906001600160a01b03168015801590610f5f575060405163b700961360e01b81526001600160a01b0382169063b700961390610f1e90879030908890600401611c94565b602060405180830381865afa158015610f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5f9190611cc1565b80610f7757506006546001600160a01b038581169116145b949350505050565b6001600160a01b03821660009081526003602052604081208054839290610fa7908490611ce3565b90915550506002805482900390556040518181526000906001600160a01b03841690600080516020611dc5833981519152906020015b60405180910390a35050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061106a5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064016106f4565b50505050565b6060814710156110955760405163cd78605960e01b81523060048201526024016106f4565b600080856001600160a01b031684866040516110b19190611cf6565b60006040518083038185875af1925050503d80600081146110ee576040519150601f19603f3d011682016040523d82523d6000602084013e6110f3565b606091505b509150915061110386838361145c565b9695505050505050565b6008546001600160a01b03161561118a57600854604051630abd626b60e41b81526001600160a01b03848116600483015283811660248301523360448301529091169063abd626b09060640160006040518083038186803b15801561117157600080fd5b505afa158015611185573d6000803e3d6000fd5b505050505b5050565b6001600160a01b038316600090815260046020908152604080832033845290915281205460001981146111ea576111c58382611ce3565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290611212908490611ce3565b90915550506001600160a01b0380851660008181526003602052604090819020805487019055519091871690600080516020611dc58339815191529061125b9087815260200190565b60405180910390a3506001949350505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516112a09190611d12565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b03841660248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061139d5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b60448201526064016106f4565b5050505050565b80600260008282546113b69190611db1565b90915550506001600160a01b038216600081815260036020908152604080832080548601905551848152600080516020611dc58339815191529101610fdd565b33600090815260036020526040812080548391908390611417908490611ce3565b90915550506001600160a01b03831660008181526003602052604090819020805485019055513390600080516020611dc5833981519152906106b19086815260200190565b6060826114715761146c826114b8565b610919565b815115801561148857506001600160a01b0384163b155b156114b157604051639996b31560e01b81526001600160a01b03851660048201526024016106f4565b5080610919565b8051156114c85780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6000602082840312156114f657600080fd5b81356001600160e01b03198116811461091957600080fd5b60005b83811015611529578181015183820152602001611511565b50506000910152565b6000815180845261154a81602086016020860161150e565b601f01601f19169290920160200192915050565b6020815260006109196020830184611532565b6001600160a01b03811681146114e157600080fd5b6000806040838503121561159957600080fd5b82356115a481611571565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115f1576115f16115b2565b604052919050565b600082601f83011261160a57600080fd5b813567ffffffffffffffff811115611624576116246115b2565b611637601f8201601f19166020016115c8565b81815284602083860101111561164c57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561167f57600080fd5b843561168a81611571565b9350602085013561169a81611571565b925060408501359150606085013567ffffffffffffffff8111156116bd57600080fd5b6116c9878288016115f9565b91505092959194509250565b600080600080600060a086880312156116ed57600080fd5b85356116f881611571565b9450602086013561170881611571565b935060408601359250606086013561171f81611571565b949793965091946080013592915050565b60008083601f84011261174257600080fd5b50813567ffffffffffffffff81111561175a57600080fd5b6020830191508360208260051b850101111561177557600080fd5b9250929050565b6000806000806000806060878903121561179557600080fd5b863567ffffffffffffffff808211156117ad57600080fd5b6117b98a838b01611730565b909850965060208901359150808211156117d257600080fd5b6117de8a838b01611730565b909650945060408901359150808211156117f757600080fd5b5061180489828a01611730565b979a9699509497509295939492505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561186b57603f19888603018452611859858351611532565b9450928501929085019060010161183d565b5092979650505050505050565b60008060006060848603121561188d57600080fd5b833561189881611571565b925060208401356118a881611571565b929592945050506040919091013590565b6000602082840312156118cb57600080fd5b813561091981611571565b600082601f8301126118e757600080fd5b8135602067ffffffffffffffff821115611903576119036115b2565b8160051b6119128282016115c8565b928352848101820192828101908785111561192c57600080fd5b83870192505b8483101561194b57823582529183019190830190611932565b979650505050505050565b600080600080600060a0868803121561196e57600080fd5b853561197981611571565b9450602086013561198981611571565b9350604086013567ffffffffffffffff808211156119a657600080fd5b6119b289838a016118d6565b945060608801359150808211156119c857600080fd5b6119d489838a016118d6565b935060808801359150808211156119ea57600080fd5b506119f7888289016115f9565b9150509295509295909350565b600080600080600080600060e0888a031215611a1f57600080fd5b8735611a2a81611571565b96506020880135611a3a81611571565b95506040880135945060608801359350608088013560ff81168114611a5e57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611a8e57600080fd5b8235611a9981611571565b91506020830135611aa981611571565b809150509250929050565b600080600080600060a08688031215611acc57600080fd5b8535611ad781611571565b94506020860135611ae781611571565b93506040860135925060608601359150608086013567ffffffffffffffff811115611b1157600080fd5b6119f7888289016115f9565b60008060008060608587031215611b3357600080fd5b8435611b3e81611571565b9350602085013567ffffffffffffffff80821115611b5b57600080fd5b818701915087601f830112611b6f57600080fd5b813581811115611b7e57600080fd5b886020828501011115611b9057600080fd5b95986020929092019750949560400135945092505050565b600181811c90821680611bbc57607f821691505b602082108103611bdc57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112611c3557600080fd5b83018035915067ffffffffffffffff821115611c5057600080fd5b60200191503681900382131561177557600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611c8d57611c8d611c65565b5060010190565b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b600060208284031215611cd357600080fd5b8151801515811461091957600080fd5b818103818111156105c2576105c2611c65565b60008251611d0881846020870161150e565b9190910192915050565b600080835481600182811c915080831680611d2e57607f831692505b60208084108203611d4d57634e487b7160e01b86526022600452602486fd5b818015611d615760018114611d7657611da3565b60ff1986168952841515850289019650611da3565b60008a81526020902060005b86811015611d9b5781548b820152908501908301611d82565b505084890196505b509498975050505050505050565b808201808211156105c2576105c2611c6556feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220de0e50aca3a032802c7c415f6c52454b3ad8c884932f481b5836056ca11d843d64736f6c634300081500330000000000000000000000005f2f11ad8656439d5c14d9b351f8b09cdac2a02d000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009536f6e696320555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057363555344000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101855760003560e01c80637ecebe00116100d1578063bc197c811161008a578063dd62ed3e11610064578063dd62ed3e146104ed578063f23a6e6114610525578063f2fde38b14610551578063f6e715d01461057157600080fd5b8063bc197c8114610481578063bf7e214f146104ad578063d505accf146104cd57600080fd5b80637ecebe00146103a75780637f5a7c7b146103d45780638929565f1461040c5780638da5cb5b1461042c57806395d89b411461044c578063a9059cbb1461046157600080fd5b8063224d87031161013e5780633644e515116101185780633644e5151461032557806339d6ba321461033a57806370a082311461035a5780637a9e5e4b1461038757600080fd5b8063224d87031461029257806323b872dd146102bf578063313ce567146102df57600080fd5b806301ffc9a71461019157806306fdde03146101c6578063095ea7b3146101e8578063150b7a021461020857806318160ddd1461024c57806318457e611461027057600080fd5b3661018c57005b600080fd5b34801561019d57600080fd5b506101b16101ac3660046114e4565b610591565b60405190151581526020015b60405180910390f35b3480156101d257600080fd5b506101db6105c8565b6040516101bd919061155e565b3480156101f457600080fd5b506101b1610203366004611586565b610656565b34801561021457600080fd5b50610233610223366004611669565b630a85bd0160e11b949350505050565b6040516001600160e01b031990911681526020016101bd565b34801561025857600080fd5b5061026260025481565b6040519081526020016101bd565b34801561027c57600080fd5b5061029061028b3660046116d5565b6106c2565b005b34801561029e57600080fd5b506102b26102ad36600461177c565b610788565b6040516101bd9190611816565b3480156102cb57600080fd5b506101b16102da366004611878565b6108ff565b3480156102eb57600080fd5b506103137f000000000000000000000000000000000000000000000000000000000000000681565b60405160ff90911681526020016101bd565b34801561033157600080fd5b50610262610920565b34801561034657600080fd5b506102906103553660046116d5565b61097b565b34801561036657600080fd5b506102626103753660046118b9565b60036020526000908152604090205481565b34801561039357600080fd5b506102906103a23660046118b9565b610a2a565b3480156103b357600080fd5b506102626103c23660046118b9565b60056020526000908152604090205481565b3480156103e057600080fd5b506008546103f4906001600160a01b031681565b6040516001600160a01b0390911681526020016101bd565b34801561041857600080fd5b506102906104273660046118b9565b610b14565b34801561043857600080fd5b506006546103f4906001600160a01b031681565b34801561045857600080fd5b506101db610b68565b34801561046d57600080fd5b506101b161047c366004611586565b610b75565b34801561048d57600080fd5b5061023361049c366004611956565b63bc197c8160e01b95945050505050565b3480156104b957600080fd5b506007546103f4906001600160a01b031681565b3480156104d957600080fd5b506102906104e8366004611a04565b610b8b565b3480156104f957600080fd5b50610262610508366004611a7b565b600460209081526000928352604080842090915290825290205481565b34801561053157600080fd5b50610233610540366004611ab4565b63f23a6e6160e01b95945050505050565b34801561055d57600080fd5b5061029061056c3660046118b9565b610dcf565b34801561057d57600080fd5b506101db61058c366004611b1d565b610e4d565b60006001600160e01b03198216630271189760e51b14806105c257506301ffc9a760e01b6001600160e01b03198316145b92915050565b600080546105d590611ba8565b80601f016020809104026020016040519081016040528092919081815260200182805461060190611ba8565b801561064e5780601f106106235761010080835404028352916020019161064e565b820191906000526020600020905b81548152906001019060200180831161063157829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106b19086815260200190565b60405180910390a350600192915050565b6106d8336000356001600160e01b031916610ed5565b6106fd5760405162461bcd60e51b81526004016106f490611be2565b60405180910390fd5b6107078282610f7f565b8215610721576107216001600160a01b0385168685610fe9565b816001600160a01b0316846001600160a01b0316866001600160a01b03167fe0c82280a1164680e0cf43be7db4c4c9f985423623ad7a544fb76c772bdc60438685604051610779929190918252602082015260400190565b60405180910390a45050505050565b60606107a0336000356001600160e01b031916610ed5565b6107bc5760405162461bcd60e51b81526004016106f490611be2565b858067ffffffffffffffff8111156107d6576107d66115b2565b60405190808252806020026020018201604052801561080957816020015b60608152602001906001900390816107f45790505b50915060005b818110156108f3576108c587878381811061082c5761082c611c08565b905060200281019061083e9190611c1e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525089925088915085905081811061088757610887611c08565b905060200201358b8b858181106108a0576108a0611c08565b90506020020160208101906108b591906118b9565b6001600160a01b03169190611070565b8382815181106108d7576108d7611c08565b6020026020010181905250806108ec90611c7b565b905061080f565b50509695505050505050565b600061090b848461110d565b61091684848461118e565b90505b9392505050565b60007f000000000000000000000000000000000000000000000000000000000000009246146109565761095161126e565b905090565b507f9483f09381344aa2a2a86c1f501c7724c4dc51e015826046e84647b208139b3090565b610991336000356001600160e01b031916610ed5565b6109ad5760405162461bcd60e51b81526004016106f490611be2565b82156109c8576109c86001600160a01b038516863086611308565b6109d282826113a4565b816001600160a01b0316846001600160a01b0316866001600160a01b03167fea00f88768a86184a6e515238a549c171769fe7460a011d6fd0bcd48ca078ea48685604051610779929190918252602082015260400190565b6006546001600160a01b0316331480610abf575060075460405163b700961360e01b81526001600160a01b039091169063b700961390610a7e90339030906001600160e01b03196000351690600401611c94565b602060405180830381865afa158015610a9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610abf9190611cc1565b610ac857600080fd5b600780546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b610b2a336000356001600160e01b031916610ed5565b610b465760405162461bcd60e51b81526004016106f490611be2565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b600180546105d590611ba8565b6000610b81338461110d565b61091983836113f6565b42841015610bdb5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064016106f4565b60006001610be7610920565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610cf3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610d295750876001600160a01b0316816001600160a01b0316145b610d665760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b60448201526064016106f4565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b610de5336000356001600160e01b031916610ed5565b610e015760405162461bcd60e51b81526004016106f490611be2565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6060610e65336000356001600160e01b031916610ed5565b610e815760405162461bcd60e51b81526004016106f490611be2565b610ecc84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050506001600160a01b03881691905084611070565b95945050505050565b6007546000906001600160a01b03168015801590610f5f575060405163b700961360e01b81526001600160a01b0382169063b700961390610f1e90879030908890600401611c94565b602060405180830381865afa158015610f3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5f9190611cc1565b80610f7757506006546001600160a01b038581169116145b949350505050565b6001600160a01b03821660009081526003602052604081208054839290610fa7908490611ce3565b90915550506002805482900390556040518181526000906001600160a01b03841690600080516020611dc5833981519152906020015b60405180910390a35050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061106a5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b60448201526064016106f4565b50505050565b6060814710156110955760405163cd78605960e01b81523060048201526024016106f4565b600080856001600160a01b031684866040516110b19190611cf6565b60006040518083038185875af1925050503d80600081146110ee576040519150601f19603f3d011682016040523d82523d6000602084013e6110f3565b606091505b509150915061110386838361145c565b9695505050505050565b6008546001600160a01b03161561118a57600854604051630abd626b60e41b81526001600160a01b03848116600483015283811660248301523360448301529091169063abd626b09060640160006040518083038186803b15801561117157600080fd5b505afa158015611185573d6000803e3d6000fd5b505050505b5050565b6001600160a01b038316600090815260046020908152604080832033845290915281205460001981146111ea576111c58382611ce3565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290611212908490611ce3565b90915550506001600160a01b0380851660008181526003602052604090819020805487019055519091871690600080516020611dc58339815191529061125b9087815260200190565b60405180910390a3506001949350505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516112a09190611d12565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b03841660248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061139d5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b60448201526064016106f4565b5050505050565b80600260008282546113b69190611db1565b90915550506001600160a01b038216600081815260036020908152604080832080548601905551848152600080516020611dc58339815191529101610fdd565b33600090815260036020526040812080548391908390611417908490611ce3565b90915550506001600160a01b03831660008181526003602052604090819020805485019055513390600080516020611dc5833981519152906106b19086815260200190565b6060826114715761146c826114b8565b610919565b815115801561148857506001600160a01b0384163b155b156114b157604051639996b31560e01b81526001600160a01b03851660048201526024016106f4565b5080610919565b8051156114c85780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6000602082840312156114f657600080fd5b81356001600160e01b03198116811461091957600080fd5b60005b83811015611529578181015183820152602001611511565b50506000910152565b6000815180845261154a81602086016020860161150e565b601f01601f19169290920160200192915050565b6020815260006109196020830184611532565b6001600160a01b03811681146114e157600080fd5b6000806040838503121561159957600080fd5b82356115a481611571565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156115f1576115f16115b2565b604052919050565b600082601f83011261160a57600080fd5b813567ffffffffffffffff811115611624576116246115b2565b611637601f8201601f19166020016115c8565b81815284602083860101111561164c57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000806080858703121561167f57600080fd5b843561168a81611571565b9350602085013561169a81611571565b925060408501359150606085013567ffffffffffffffff8111156116bd57600080fd5b6116c9878288016115f9565b91505092959194509250565b600080600080600060a086880312156116ed57600080fd5b85356116f881611571565b9450602086013561170881611571565b935060408601359250606086013561171f81611571565b949793965091946080013592915050565b60008083601f84011261174257600080fd5b50813567ffffffffffffffff81111561175a57600080fd5b6020830191508360208260051b850101111561177557600080fd5b9250929050565b6000806000806000806060878903121561179557600080fd5b863567ffffffffffffffff808211156117ad57600080fd5b6117b98a838b01611730565b909850965060208901359150808211156117d257600080fd5b6117de8a838b01611730565b909650945060408901359150808211156117f757600080fd5b5061180489828a01611730565b979a9699509497509295939492505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561186b57603f19888603018452611859858351611532565b9450928501929085019060010161183d565b5092979650505050505050565b60008060006060848603121561188d57600080fd5b833561189881611571565b925060208401356118a881611571565b929592945050506040919091013590565b6000602082840312156118cb57600080fd5b813561091981611571565b600082601f8301126118e757600080fd5b8135602067ffffffffffffffff821115611903576119036115b2565b8160051b6119128282016115c8565b928352848101820192828101908785111561192c57600080fd5b83870192505b8483101561194b57823582529183019190830190611932565b979650505050505050565b600080600080600060a0868803121561196e57600080fd5b853561197981611571565b9450602086013561198981611571565b9350604086013567ffffffffffffffff808211156119a657600080fd5b6119b289838a016118d6565b945060608801359150808211156119c857600080fd5b6119d489838a016118d6565b935060808801359150808211156119ea57600080fd5b506119f7888289016115f9565b9150509295509295909350565b600080600080600080600060e0888a031215611a1f57600080fd5b8735611a2a81611571565b96506020880135611a3a81611571565b95506040880135945060608801359350608088013560ff81168114611a5e57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215611a8e57600080fd5b8235611a9981611571565b91506020830135611aa981611571565b809150509250929050565b600080600080600060a08688031215611acc57600080fd5b8535611ad781611571565b94506020860135611ae781611571565b93506040860135925060608601359150608086013567ffffffffffffffff811115611b1157600080fd5b6119f7888289016115f9565b60008060008060608587031215611b3357600080fd5b8435611b3e81611571565b9350602085013567ffffffffffffffff80821115611b5b57600080fd5b818701915087601f830112611b6f57600080fd5b813581811115611b7e57600080fd5b886020828501011115611b9057600080fd5b95986020929092019750949560400135945092505050565b600181811c90821680611bbc57607f821691505b602082108103611bdc57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112611c3557600080fd5b83018035915067ffffffffffffffff821115611c5057600080fd5b60200191503681900382131561177557600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611c8d57611c8d611c65565b5060010190565b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b600060208284031215611cd357600080fd5b8151801515811461091957600080fd5b818103818111156105c2576105c2611c65565b60008251611d0881846020870161150e565b9190910192915050565b600080835481600182811c915080831680611d2e57607f831692505b60208084108203611d4d57634e487b7160e01b86526022600452602486fd5b818015611d615760018114611d7657611da3565b60ff1986168952841515850289019650611da3565b60008a81526020902060005b86811015611d9b5781548b820152908501908301611d82565b505084890196505b509498975050505050505050565b808201808211156105c2576105c2611c6556feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220de0e50aca3a032802c7c415f6c52454b3ad8c884932f481b5836056ca11d843d64736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005f2f11ad8656439d5c14d9b351f8b09cdac2a02d000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000009536f6e696320555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057363555344000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _owner (address): 0x5F2F11ad8656439d5C14d9B351f8b09cDaC2A02d
Arg [1] : _name (string): Sonic USD
Arg [2] : _symbol (string): scUSD
Arg [3] : _decimals (uint8): 6
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000005f2f11ad8656439d5c14d9b351f8b09cdac2a02d
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [5] : 536f6e6963205553440000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [7] : 7363555344000000000000000000000000000000000000000000000000000000
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.