More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 77 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Release | 16961834 | 663 days ago | IN | 0 ETH | 0.00197028 | ||||
Release | 16878087 | 675 days ago | IN | 0 ETH | 0.00121638 | ||||
Release | 16878077 | 675 days ago | IN | 0 ETH | 0.00141849 | ||||
Release | 16840009 | 680 days ago | IN | 0 ETH | 0.00170315 | ||||
Release | 16835883 | 681 days ago | IN | 0 ETH | 0.00192701 | ||||
Release | 16833984 | 681 days ago | IN | 0 ETH | 0.00400912 | ||||
Release | 16832431 | 682 days ago | IN | 0 ETH | 0.00182758 | ||||
Release | 16828587 | 682 days ago | IN | 0 ETH | 0.00186984 | ||||
Release | 16827852 | 682 days ago | IN | 0 ETH | 0.00360393 | ||||
Release | 16827659 | 682 days ago | IN | 0 ETH | 0.00367568 | ||||
Release | 16827435 | 682 days ago | IN | 0 ETH | 0.00224256 | ||||
Release | 16827411 | 682 days ago | IN | 0 ETH | 0.00409083 | ||||
Release | 16826663 | 682 days ago | IN | 0 ETH | 0.00291785 | ||||
Release | 16822767 | 683 days ago | IN | 0 ETH | 0.00153102 | ||||
Release | 16822731 | 683 days ago | IN | 0 ETH | 0.00132622 | ||||
Release | 16822726 | 683 days ago | IN | 0 ETH | 0.00206986 | ||||
Release | 16822080 | 683 days ago | IN | 0 ETH | 0.00145244 | ||||
Deposit | 16812904 | 684 days ago | IN | 0.1 ETH | 0.00558633 | ||||
Deposit With Aff... | 16810803 | 685 days ago | IN | 0.04 ETH | 0.00598285 | ||||
Release | 16796423 | 687 days ago | IN | 0 ETH | 0.0014187 | ||||
Release | 16796372 | 687 days ago | IN | 0 ETH | 0.00154233 | ||||
Release | 16796367 | 687 days ago | IN | 0 ETH | 0.00233315 | ||||
Deposit | 16776404 | 689 days ago | IN | 0.0499773 ETH | 0.00607257 | ||||
Release | 16644140 | 708 days ago | IN | 0 ETH | 0.00242056 | ||||
Transfer | 16620996 | 711 days ago | IN | 0 ETH | 0.00074914 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
16812904 | 684 days ago | 0.1 ETH | ||||
16810803 | 685 days ago | 0.04 ETH | ||||
16776404 | 689 days ago | 0.0499773 ETH | ||||
16614704 | 712 days ago | 0.03355357 ETH | ||||
16346219 | 750 days ago | 0.05426424 ETH | ||||
16283016 | 758 days ago | 0.05077499 ETH | ||||
16005330 | 797 days ago | 0.05 ETH | ||||
15970740 | 802 days ago | 0.13 ETH | ||||
15939328 | 806 days ago | 0.0433 ETH | ||||
15936415 | 807 days ago | 0.1679966 ETH | ||||
15936410 | 807 days ago | 0.2 ETH | ||||
15921579 | 809 days ago | 0.0325 ETH | ||||
15905482 | 811 days ago | 0.04394999 ETH | ||||
15899097 | 812 days ago | 0.05180054 ETH | ||||
15861314 | 817 days ago | 0.12 ETH | ||||
15860570 | 817 days ago | 0.60353264 ETH | ||||
15845825 | 819 days ago | 0.29 ETH | ||||
15752596 | 833 days ago | 0.53 ETH | ||||
15740241 | 834 days ago | 0.08 ETH | ||||
15677123 | 843 days ago | 0.0588 ETH | ||||
15667346 | 844 days ago | 0.06492507 ETH | ||||
15662735 | 845 days ago | 0.109 ETH | ||||
15661689 | 845 days ago | 0.055 ETH | ||||
15641987 | 848 days ago | 0.075 ETH | ||||
15641584 | 848 days ago | 0.038 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CrowdsaleFull
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@amxx/hre/contracts/tokens/utils/Balances.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import "./modules/ERC20Buyable.sol"; import "./modules/ERC20Vesting.sol"; contract CrowdsaleFull is ERC20Buyable, ERC20Vesting { using Balances for Balances.Fungible; uint256 public immutable buyInMinimum; uint64 public immutable saleStart; uint64 public immutable saleStop; Balances.Fungible private _bonus; event AffiliationBonus(address indexed affiliate, address indexed user, uint256 affiliateAmount, uint256 userAmount); modifier onlyDuringSale() { require(block.timestamp >= saleStart && block.timestamp < saleStop, "sale not active"); _; } modifier onlyAfterSale() { require(block.timestamp >= saleStop, "sale not over"); _; } constructor( ISwapRouter uniswapRouter_, IQuoter uniswapQuoter_, IERC20 USDC_, IERC20 token_, uint256 rate_, uint64 saleStart_, uint64 saleDuration_, uint64 vestingStart_, uint64 cliffDuration_, uint64 vestingDuration_, uint256 buyInMinimum_ ) ERC20("FeelingMeta Crowdsale - Phase 1", "xFM #1") SwapToUSDC(uniswapRouter_, uniswapQuoter_, USDC_) ERC20Buyable(rate_) ERC20Vesting(token_, vestingStart_, vestingStart_ + vestingDuration_, vestingStart_ + cliffDuration_) { saleStart = saleStart_; saleStop = saleDuration_ == 0 ? type(uint64).max : saleStart_ + saleDuration_; buyInMinimum = buyInMinimum_; } function bonusOf(address user_) public view returns (uint256) { return _bonus.balanceOf(user_); } function totalBonus() public view returns (uint256) { return _bonus.totalSupply(); } /// Restrict deposit time function deposit( address receiver_, uint256 amountIn_, uint256 minimumTokenOut_, bytes memory path_ ) public payable virtual onlyDuringSale() returns (uint256) { uint256 remaining = token.balanceOf(address(this)) - totalSupply(); require(remaining > 0, "Sold out"); uint256 amount = _deposit(receiver_, amountIn_, minimumTokenOut_, cost(remaining), path_); require(amount == remaining || amount >= buyInMinimum, "Minimum buy-in not reached"); // If payment in ether, and remaining value if (msg.value > 0 && address(this).balance > 0) { // sending it back to the caller Address.sendValue(payable(msg.sender), address(this).balance); } return amount; } function depositWithAffiliate( address receiver_, address affiliate_, uint256 amountIn_, uint256 minimumTokenOut_, bytes memory path_ ) public payable virtual returns (uint256) { uint256 amount = deposit(receiver_, amountIn_, minimumTokenOut_, path_); _bonus.mint(receiver_, amount * 5 / 100); _bonus.mint(affiliate_, amount * 15 / 100); emit AffiliationBonus(affiliate_, receiver_, amount * 15 / 100, amount * 5 / 100); return amount; } function drain(IERC20 token_, address receiver_) public onlyOwner() { require(token != token_); SafeERC20.safeTransfer(token_, receiver_, token_.balanceOf(address(this))); } function burnExtra() public onlyAfterSale() { ERC20Burnable(address(token)).burn(token.balanceOf(address(this)) + totalReleased() - totalSupply()); } /// overrides function _transfer(address from, address to, uint256 amount) internal virtual override(ERC20, ERC20Vesting) { super._transfer(from, to, amount); } function _mint(address to, uint256 amount) internal virtual override { super._mint(to, amount); require(totalSupply() <= token.balanceOf(address(this)), "Sold out"); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "./Distributions.sol"; library Balances { using Distributions for Distributions.Uint256; using EnumerableSet for EnumerableSet.UintSet; struct Fungible { Distributions.Uint256 _balances; } function balanceOf(Fungible storage self, address account) internal view returns (uint256) { return self._balances.valueOf(account); } function totalSupply(Fungible storage self) internal view returns (uint256) { return self._balances.total(); } function mint(Fungible storage self, address to, uint256 amount) internal { self._balances.incr(to, amount); } function burn(Fungible storage self, address from, uint256 amount) internal { require(self._balances.valueOf(from) >= amount, "burn amount exceeds balance"); self._balances.decr(from, amount); } function transfer(Fungible storage self, address from, address to, uint256 amount) internal { require(self._balances.valueOf(from) >= amount, "transfer amount exceeds balance"); self._balances.mv(from, to, amount); } struct NonFungible { mapping(uint256 => address) _owner; } function ownerOf(NonFungible storage self, uint256 tokenid) internal view returns (address) { return self._owner[tokenid]; } function mint(NonFungible storage self, address to, uint256 tokenid) internal { require(ownerOf(self, tokenid) == address(0), "token already exists"); self._owner[tokenid] = to; } function burn(NonFungible storage self, address from, uint256 tokenid) internal { require(ownerOf(self, tokenid) == from, "token doesn't exist"); self._owner[tokenid] = address(0); } function transfer(NonFungible storage self, address from, address to, uint256 tokenid) internal { require(ownerOf(self, tokenid) == from, "token doesn't exist"); self._owner[tokenid] = to; } // struct NonFungibleEnumerable { // NonFungible _base; // EnumerableSet.UintSet _allTokens; // mapping(address => EnumerableSet.UintSet) _userTokens; // } // function balanceOf(NonFungibleEnumerable storage self, address account) internal view returns (uint256) { // return self._userTokens[account].length(); // } // function at(NonFungibleEnumerable storage self, address account, uint256 idx) internal view returns (uint256) { // return self._userTokens[account].at(idx); // } // function totalSupply(NonFungibleEnumerable storage self) internal view returns (uint256) { // return self._allTokens.length(); // } // function at(NonFungibleEnumerable storage self, uint256 idx) internal view returns (uint256) { // return self._allTokens.at(idx); // } // function ownerOf(NonFungibleEnumerable storage self, uint256 tokenid) internal view returns (address) { // return ownerOf(self._base, tokenid); // } // function mint(NonFungibleEnumerable storage self, address to, uint256 tokenid) internal { // mint(self._base, to, tokenid); // self._allTokens.add(tokenid); // self._userTokens[to].add(tokenid); // } // function burn(NonFungibleEnumerable storage self, address from, uint256 tokenid) internal { // burn(self._base, from, tokenid); // self._allTokens.remove(tokenid); // self._userTokens[from].remove(tokenid); // } // function transfer(NonFungibleEnumerable storage self, address from, address to, uint256 tokenid) internal { // transfer(self._base, from, to, tokenid); // self._userTokens[from].remove(tokenid); // self._userTokens[to].add(tokenid); // } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.0; import "../ERC20.sol"; import "../../../utils/Context.sol"; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { _spendAllowance(account, _msgSender(), amount); _burn(account, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "./SwapToUSDC.sol"; abstract contract ERC20Buyable is ERC20, Ownable, SwapToUSDC { uint256 immutable private _rate; constructor(uint256 rate_) { _rate = rate_; } function _deposit(address receiver_, uint256 amountIn_, uint256 amountOutMinimum_, uint256 amountOutMax_, bytes memory path_) internal virtual returns (uint256) { uint256 received = _swap(owner(), amountIn_, amountOutMinimum_, amountOutMax_, path_); uint256 amount = conversion(received); _mint(receiver_, amount); return amount; } function conversion(uint256 received_) public view virtual returns (uint256) { // 30 = 18 (this.decimals) + 18 (rate denominator) - 6 (USDC.decimals) return received_ * (10 ** 30) / _rate; } function cost(uint256 output_) public view virtual returns (uint256) { return output_ * _rate / (10 ** 30); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@amxx/hre/contracts/tokens/utils/Balances.sol"; import "@amxx/hre/contracts/math/CommonFunctions.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; abstract contract ERC20Vesting is ERC20 { using Balances for Balances.Fungible; IERC20 immutable public token; uint64 immutable public vestingStart; uint64 immutable public vestingStop; uint64 immutable public cliff; Balances.Fungible private _released; constructor(IERC20 token_, uint64 vestingStart_, uint64 vestingStop_, uint64 cliff_) { token = token_; vestingStart = vestingStart_; vestingStop = vestingStop_; cliff = cliff_; } function released(address user_) public view returns (uint256) { return _released.balanceOf(user_); } function totalReleased() public view returns (uint256) { return _released.totalSupply(); } function vested(uint256 amount_, uint64 timestamp_) public view virtual returns (uint256) { return CommonFunctions.ramp( vestingStart, vestingStop, CommonFunctions.heaviside(cliff, amount_, timestamp_), timestamp_ ); } function releasable(address user_) public view virtual returns (uint256) { uint256 alreadyReleased = released(user_); return vested(balanceOf(user_) + alreadyReleased, uint64(block.timestamp)) - alreadyReleased; } function release(address user_) public virtual returns (uint256) { uint256 toRelease = releasable(user_); _released.mint(user_, toRelease); _burn(user_, toRelease); SafeERC20.safeTransfer(token, user_, toRelease); return toRelease; } /// Disable transfer function _transfer(address, address, uint256) internal virtual override { revert('cannot transfer shares'); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0-rc.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Distributions { struct Uint256 { mapping(address => uint256) _values; uint256 _total; } function valueOf(Uint256 storage self, address account) internal view returns (uint256) { return self._values[account]; } function total(Uint256 storage self) internal view returns (uint256) { return self._total; } function set(Uint256 storage self, address account, uint256 amount) internal { self._total = self._total - self._values[account] + amount; self._values[account] = amount; } function incr(Uint256 storage self, address account, uint256 amount) internal { self._total += amount; self._values[account] += amount; } function decr(Uint256 storage self, address account, uint256 amount) internal { self._total -= amount; self._values[account] -= amount; } function mv(Uint256 storage self, address from, address to, uint256 amount) internal { self._values[from] -= amount; self._values[to] += amount; } struct Int256 { mapping(address => int256) _values; int256 _total; } function valueOf(Int256 storage self, address account) internal view returns (int256) { return self._values[account]; } function total(Int256 storage self) internal view returns (int256) { return self._total; } function set(Int256 storage self, address account, int256 amount) internal { self._total += amount - self._values[account]; self._values[account] = amount; } function incr(Int256 storage self, address account, int256 amount) internal { self._total += amount; self._values[account] += amount; } function decr(Int256 storage self, address account, int256 amount) internal { self._total -= amount; self._values[account] -= amount; } function mv(Int256 storage self, address from, address to, int256 amount) internal { self._values[from] -= amount; self._values[to] += amount; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0-rc.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0-rc.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol"; import "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol"; import "@uniswap/v3-periphery/contracts/interfaces/IPeripheryImmutableState.sol"; import "solidity-bytes-utils/contracts/BytesLib.sol"; import "../../interfaces/IWETH9.sol"; abstract contract SwapToUSDC { using BytesLib for bytes; ISwapRouter immutable public uniswapRouter; IQuoter immutable public uniswapQuoter; IWETH9 immutable public WETH; IERC20 immutable public USDC; constructor(ISwapRouter uniswapRouter_, IQuoter uniswapQuoter_, IERC20 USDC_) { uniswapRouter = uniswapRouter_; uniswapQuoter = uniswapQuoter_; USDC = USDC_; WETH = IWETH9(IPeripheryImmutableState(address(uniswapRouter_)).WETH9()); } function _swap(address receiver_, uint256 amountIn_, uint256 amountOutMinimum_, uint256 amountOutMaximum_, bytes memory path_) internal returns (uint256) { // Set override for ETH / Check path if (msg.value > 0) { // if we have value, force WETH <> USDC swap amountIn_ = msg.value; path_ = abi.encodePacked(WETH, uint24(3000), USDC); } else if (path_.length > 0) { require(IERC20(path_.toAddress(path_.length - 20)) == USDC, "invalid-token-output"); } // don't swap to much if (amountOutMaximum_ < type(uint256).max) { if (path_.length == 0) { // If no path, we are dealing with USDC everywhere amountIn_ = Math.min(amountIn_, amountOutMaximum_); } else { // Otherwize use the quoter: note that this may revert, in which case we disregard the check try uniswapQuoter.quoteExactOutput(reversePath(path_), amountOutMaximum_) returns (uint256 amountInMax) { amountIn_ = Math.min(amountIn_, amountInMax); } catch {} } } // No value and a path, we need to take custody of the token and approve the router if (msg.value == 0 && path_.length > 0) { IERC20 assetIn = IERC20(path_.toAddress(0)); SafeERC20.safeTransferFrom(assetIn, msg.sender, address(this), amountIn_); SafeERC20.safeApprove(assetIn, address(uniswapRouter), amountIn_); } if (path_.length == 0) { SafeERC20.safeTransferFrom( USDC, msg.sender, receiver_, amountIn_ ); return amountIn_; } else { return uniswapRouter.exactInput{ value: msg.value == 0 ? 0 : amountIn_ }(ISwapRouter.ExactInputParams({ path: path_, recipient: receiver_, deadline: block.timestamp, amountIn: amountIn_, amountOutMinimum: amountOutMinimum_ })); } } } function reversePath(bytes memory path) pure returns (bytes memory) { uint256 count = (path.length - 20) / 23; bytes memory rpath = new bytes(path.length); assembly { let pathOffset := mul(count, 0x17) let rpathOffset := 0 for {} gt(pathOffset, 0) { pathOffset := sub(pathOffset, 0x17) rpathOffset := add(rpathOffset, 0x17) } { let buffer := mload(add(path, add(pathOffset, 0x1D))) mstore( add(rpath, add(rpathOffset, 0x20)), shl(0x18, and(buffer, 0x000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000)) ) mstore( add(rpath, add(rpathOffset, 0x34)), and(buffer, 0xFFFFFF0000000000000000000000000000000000000000000000000000000000) ) } mstore( add(rpath, add(rpathOffset, 0x20)), and(mload(add(path, 0x20)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000) ) } return rpath; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0-rc.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0-rc.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a // good first aproximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 1; } // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; /// @title Quoter Interface /// @notice Supports quoting the calculated amounts from exact input or exact output swaps /// @dev These functions are not marked view because they rely on calling non-view functions and reverting /// to compute the result. They are also not gas efficient and should not be called on-chain. interface IQuoter { /// @notice Returns the amount out received for a given exact input swap without executing the swap /// @param path The path of the swap, i.e. each token pair and the pool fee /// @param amountIn The amount of the first token to swap /// @return amountOut The amount of the last token that would be received function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut); /// @notice Returns the amount out received for a given exact input but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountIn The desired input amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountOut The amount of `tokenOut` that would be received function quoteExactInputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountOut); /// @notice Returns the amount in required for a given exact output swap without executing the swap /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order /// @param amountOut The amount of the last token to receive /// @return amountIn The amount of first token required to be paid function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn); /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountOut The desired output amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountIn The amount required as the input for the swap in order to receive `amountOut` function quoteExactOutputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountOut, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountIn); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Immutable state /// @notice Functions that return immutable state of the router interface IPeripheryImmutableState { /// @return Returns the address of the Uniswap V3 factory function factory() external view returns (address); /// @return Returns the address of WETH9 function WETH9() external view returns (address); }
// SPDX-License-Identifier: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IWETH9 is IERC20 { event Deposit(address indexed dst, uint wad); event Withdrawal(address indexed src, uint wad); function deposit() external payable; function withdraw(uint256) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0-rc.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @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, it is bubbled up by this * function (like regular Solidity function calls). * * 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. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @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`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // 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(errorMessage); } } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library CommonFunctions { /** * y ▲ * │ * │ * ymax │ ┌──────────────── * │ │ * │ │ * ─────┼──────┴────────────────► * │ x0 x **/ function heaviside(uint256 x0, uint256 ymax, uint256 x) internal pure returns (uint256) { return x >= x0 ? ymax : 0; } /** * y ▲ * │ * │ * ymax │ ┌───────┐ * │ │ │ * │ │ │ * ─────┼──────┴───────┴────────► * │ x0 x1 x **/ function rectangular(uint256 x0, uint256 x1, uint256 ymax, uint256 x) internal pure returns (uint256) { return heaviside(x0, ymax, x) - heaviside(x1, ymax, x); } /** * y ▲ / * │ / * │ / * │ / * │ / * │ / * ─────┼───────/───────────────► * │ x0 x **/ function slope(uint256 x0, uint256 x) internal pure returns (uint256) { return x >= x0 ? x - x0: 0; } /** * y ▲ * │ * │ * ymax │ ───────────── * │ / * │ / * ─────┼───────/───────────────► * │ x0 x1 x **/ function ramp(uint256 x0, uint256 x1, uint256 ymax, uint256 x) internal pure returns (uint256) { return ymax * (slope(x0, x) - slope(x1, x)) / (x1 - x0); } /** * y ▲ * │ * │ * ymax │ /\ * │ / \ * │ / \ * ─────┼───────/──────\────────► * │ x0 xmax x1 x **/ function triangle(uint256 x0, uint256 xmax, uint256 x1, uint256 ymax, uint256 x) internal pure returns (uint256) { return ramp(x0, xmax, ymax, x) - ramp(xmax, x1, ymax, x); } /** * y ▲ ┌───── * │ ←xstep→ │ * │ ┌─────┘ * │ │ * │ ┌─────┘ * │ │ * ─────┼─────┴─────────────────► * │ x **/ function step(uint256 xstep, uint256 x) internal pure returns (uint256) { return x / xstep * xstep; } /** * y ▲ * │ * │ ←x1→ ←x1→ ←x1→ * ymax │ ┌──┐ ┌──┐ ┌──┐ ┌─ * │ │ │ │ │ │ │ │ * │ │ │ │ │ │ │ │ * ─────┼──┴──┴──┴──┴──┴──┴──┴──► * │ ←x0→ ←x0→ ←x0→ x **/ function slots(uint256 x0, uint256 x1, uint256 ymax, uint256 x) internal pure returns (uint256) { uint256 period = x0 + x1; return ymax * ((x + x1) / period - x / period); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "debug": { "revertStrings": "strip" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ISwapRouter","name":"uniswapRouter_","type":"address"},{"internalType":"contract IQuoter","name":"uniswapQuoter_","type":"address"},{"internalType":"contract IERC20","name":"USDC_","type":"address"},{"internalType":"contract IERC20","name":"token_","type":"address"},{"internalType":"uint256","name":"rate_","type":"uint256"},{"internalType":"uint64","name":"saleStart_","type":"uint64"},{"internalType":"uint64","name":"saleDuration_","type":"uint64"},{"internalType":"uint64","name":"vestingStart_","type":"uint64"},{"internalType":"uint64","name":"cliffDuration_","type":"uint64"},{"internalType":"uint64","name":"vestingDuration_","type":"uint64"},{"internalType":"uint256","name":"buyInMinimum_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"affiliate","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"affiliateAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"userAmount","type":"uint256"}],"name":"AffiliationBonus","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH9","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","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":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user_","type":"address"}],"name":"bonusOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnExtra","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buyInMinimum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cliff","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"received_","type":"uint256"}],"name":"conversion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"output_","type":"uint256"}],"name":"cost","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":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"},{"internalType":"uint256","name":"minimumTokenOut_","type":"uint256"},{"internalType":"bytes","name":"path_","type":"bytes"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"address","name":"affiliate_","type":"address"},{"internalType":"uint256","name":"amountIn_","type":"uint256"},{"internalType":"uint256","name":"minimumTokenOut_","type":"uint256"},{"internalType":"bytes","name":"path_","type":"bytes"}],"name":"depositWithAffiliate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token_","type":"address"},{"internalType":"address","name":"receiver_","type":"address"}],"name":"drain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user_","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user_","type":"address"}],"name":"release","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user_","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleStart","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"saleStop","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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"},{"inputs":[],"name":"uniswapQuoter","outputs":[{"internalType":"contract IQuoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint64","name":"timestamp_","type":"uint64"}],"name":"vested","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingStart","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingStop","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6102006040523480156200001257600080fd5b506040516200267d3803806200267d833981016040819052620000359162000277565b878462000043848262000354565b6200004f868862000354565b8a8f8f8f6040518060400160405280601f81526020017f4665656c696e674d6574612043726f776473616c65202d2050686173652031008152506040518060400160405280600681526020016578464d20233160d01b8152508160039081620000b991906200042f565b506004620000c882826200042f565b505050620000e5620000df620001eb60201b60201c565b620001ef565b6001600160a01b03808416608081905283821660a05290821660e052604080516312a9293f60e21b81529051634aa4a4fc916004808201926020929091908290030181865afa1580156200013d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001639190620004fb565b6001600160a01b0390811660c0526101009490945250505093909316610120526001600160401b0391821661014052811661016052908116610180528681166101c052851615620001c057620001ba858762000354565b620001c9565b6001600160401b035b6001600160401b03166101e0526101a052506200052298505050505050505050565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03811681146200025757600080fd5b50565b80516001600160401b03811681146200027257600080fd5b919050565b60008060008060008060008060008060006101608c8e0312156200029a57600080fd5b8b51620002a78162000241565b60208d0151909b50620002ba8162000241565b60408d0151909a50620002cd8162000241565b60608d0151909950620002e08162000241565b60808d01519098509650620002f860a08d016200025a565b95506200030860c08d016200025a565b94506200031860e08d016200025a565b9350620003296101008d016200025a565b92506200033a6101208d016200025a565b91506101408c015190509295989b509295989b9093969950565b6001600160401b038181168382160190808211156200038357634e487b7160e01b600052601160045260246000fd5b5092915050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620003b557607f821691505b602082108103620003d657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200042a57600081815260208120601f850160051c81016020861015620004055750805b601f850160051c820191505b81811015620004265782815560010162000411565b5050505b505050565b81516001600160401b038111156200044b576200044b6200038a565b62000463816200045c8454620003a0565b84620003dc565b602080601f8311600181146200049b5760008415620004825750858301515b600019600386901b1c1916600185901b17855562000426565b600085815260208120601f198616915b82811015620004cc57888601518255948401946001909101908401620004ab565b5085821015620004eb5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200050e57600080fd5b81516200051b8162000241565b9392505050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161203662000647600039600081816104a301528181610a900152610e6801526000818161065a0152610a5c0152600081816106c20152610b940152600081816102c50152610de80152600081816105690152610dbb0152600081816103660152610d910152600081816107b3015281816108b70152818161094d01528181610ae401528181610e9e01528181610ef10152611781015260008181610a0d0152610d540152600081816104f701528181611490015281816114dc015261166001526000818161068e01526114580152600081816103d6015261155501526000818161046f0152818161162b015261169801526120366000f3fe6080604052600436106102255760003560e01c806393e2265911610123578063ad5c4648116100ab578063dd62ed3e1161006f578063dd62ed3e14610737578063e33b7de314610757578063edde41b21461076c578063f2fde38b14610781578063fc0c546a146107a157600080fd5b8063ad5c46481461067c578063b2adf0cc146106b0578063b5ddd347146106e4578063ba4d0c99146106f7578063cc71fadf1461071757600080fd5b8063a3f8eace116100f2578063a3f8eace146105d3578063a457c2d7146105f3578063a8dd07dc14610613578063a9059cbb14610628578063ab0bcc411461064857600080fd5b806393e226591461055757806395d89b411461058b5780639852595c146105a05780639e48ff5a146105c057600080fd5b806339509351116101b15780638078059c116101755780638078059c14610491578063837971e4146104c557806389a30271146104e55780638da5cb5b146105195780639097548d1461053757600080fd5b806339509351146103a45780634db4a352146103c457806370a0823114610410578063715018a614610446578063735de9f71461045d57600080fd5b806318160ddd116101f857806318160ddd146102ff578063191655871461031457806323b872dd14610334578063254800d414610354578063313ce5671461038857600080fd5b806306fdde031461022a578063095ea7b3146102555780631283e3281461028557806313d033c0146102b3575b600080fd5b34801561023657600080fd5b5061023f6107d5565b60405161024c9190611bd2565b60405180910390f35b34801561026157600080fd5b50610275610270366004611bfa565b610867565b604051901515815260200161024c565b34801561029157600080fd5b506102a56102a0366004611c26565b610881565b60405190815260200161024c565b3480156102bf57600080fd5b506102e77f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160401b03909116815260200161024c565b34801561030b57600080fd5b506002546102a5565b34801561032057600080fd5b506102a561032f366004611c26565b61088e565b34801561034057600080fd5b5061027561034f366004611c43565b6108dd565b34801561036057600080fd5b506102e77f000000000000000000000000000000000000000000000000000000000000000081565b34801561039457600080fd5b506040516012815260200161024c565b3480156103b057600080fd5b506102756103bf366004611bfa565b610903565b3480156103d057600080fd5b506103f87f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161024c565b34801561041c57600080fd5b506102a561042b366004611c26565b6001600160a01b031660009081526020819052604090205490565b34801561045257600080fd5b5061045b610925565b005b34801561046957600080fd5b506103f87f000000000000000000000000000000000000000000000000000000000000000081565b34801561049d57600080fd5b506102e77f000000000000000000000000000000000000000000000000000000000000000081565b3480156104d157600080fd5b5061045b6104e0366004611c84565b610939565b3480156104f157600080fd5b506103f87f000000000000000000000000000000000000000000000000000000000000000081565b34801561052557600080fd5b506005546001600160a01b03166103f8565b34801561054357600080fd5b506102a5610552366004611cbd565b6109f8565b34801561056357600080fd5b506102e77f000000000000000000000000000000000000000000000000000000000000000081565b34801561059757600080fd5b5061023f610a3c565b3480156105ac57600080fd5b506102a56105bb366004611c26565b610a4b565b6102a56105ce366004611d78565b610a58565b3480156105df57600080fd5b506102a56105ee366004611c26565b610be9565b3480156105ff57600080fd5b5061027561060e366004611bfa565b610c35565b34801561061f57600080fd5b506102a5610c6a565b34801561063457600080fd5b50610275610643366004611bfa565b610c7b565b34801561065457600080fd5b506102e77f000000000000000000000000000000000000000000000000000000000000000081565b34801561068857600080fd5b506103f87f000000000000000000000000000000000000000000000000000000000000000081565b3480156106bc57600080fd5b506102a57f000000000000000000000000000000000000000000000000000000000000000081565b6102a56106f2366004611dda565b610c89565b34801561070357600080fd5b506102a5610712366004611cbd565b610d50565b34801561072357600080fd5b506102a5610732366004611e4f565b610d8a565b34801561074357600080fd5b506102a5610752366004611c84565b610e2f565b34801561076357600080fd5b506102a5610e5a565b34801561077857600080fd5b5061045b610e66565b34801561078d57600080fd5b5061045b61079c366004611c26565b610fca565b3480156107ad57600080fd5b506103f87f000000000000000000000000000000000000000000000000000000000000000081565b6060600380546107e490611e80565b80601f016020809104026020016040519081016040528092919081815260200182805461081090611e80565b801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b5050505050905090565b600033610875818585610ff1565b60019150505b92915050565b600061087b600883611078565b60008061089a83610be9565b90506108a860068483611096565b6108b283826110a6565b61087b7f00000000000000000000000000000000000000000000000000000000000000008483611159565b6000336108eb8582856111bc565b6108f68585856111ed565b60019150505b9392505050565b6000336108758185856109168383610e2f565b6109209190611ed0565b610ff1565b61092d6111f5565b610937600061120c565b565b6109416111f5565b816001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03160361097f57600080fd5b6040516370a0823160e01b81523060048201526109f490839083906001600160a01b038316906370a0823190602401602060405180830381865afa1580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef9190611ee3565b611159565b5050565b60006c0c9f2c9cd04674edea40000000610a327f000000000000000000000000000000000000000000000000000000000000000084611efc565b61087b9190611f13565b6060600480546107e490611e80565b600061087b600683611078565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160401b03164210158015610abb57507f00000000000000000000000000000000000000000000000000000000000000006001600160401b031642105b610ac457600080fd5b6000610acf60025490565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b579190611ee3565b610b619190611f35565b905060008111610b7057600080fd5b6000610b87878787610b81866109f8565b8861125e565b905081811480610bb757507f00000000000000000000000000000000000000000000000000000000000000008110155b610bc057600080fd5b600034118015610bd05750600047115b15610bdf57610bdf33476112a3565b9695505050505050565b600080610bf583610a4b565b905080610c2b82610c1b866001600160a01b031660009081526020819052604090205490565b610c259190611ed0565b42610d8a565b6108fc9190611f35565b60003381610c438286610e2f565b905083811015610c5257600080fd5b610c5f8286868403610ff1565b506001949350505050565b6000610c766008611310565b905090565b6000336108758185856111ed565b600080610c9887868686610a58565b9050610cbe876064610cab846005611efc565b610cb59190611f13565b60089190611096565b610ccf866064610cab84600f611efc565b6001600160a01b038088169087167f08f13de638226119399e648639b1cce10d5af6854de598546e09cee33e0fdbcc6064610d0b85600f611efc565b610d159190611f13565b6064610d22866005611efc565b610d2c9190611f13565b6040805192835260208301919091520160405180910390a390505b95945050505050565b60007f0000000000000000000000000000000000000000000000000000000000000000610a32836c0c9f2c9cd04674edea40000000611efc565b60006108fc7f00000000000000000000000000000000000000000000000000000000000000006001600160401b03167f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316610e207f00000000000000000000000000000000000000000000000000000000000000006001600160401b031687876001600160401b031661131d565b856001600160401b0316611338565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6000610c766006611310565b7f00000000000000000000000000000000000000000000000000000000000000006001600160401b0316421015610e9c57600080fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166342966c68610ed460025490565b610edc610e5a565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f649190611ee3565b610f6e9190611ed0565b610f789190611f35565b6040518263ffffffff1660e01b8152600401610f9691815260200190565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050565b610fd26111f5565b6001600160a01b038116610fe557600080fd5b610fee8161120c565b50565b6001600160a01b03831661100457600080fd5b6001600160a01b03821661101757600080fd5b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0381166000908152602083905260408120546108fc565b6110a1838383611376565b505050565b6001600160a01b0382166110b957600080fd5b6001600160a01b038216600090815260208190526040902054818110156110df57600080fd5b6001600160a01b038316600090815260208190526040812083830390556002805484929061110e908490611f35565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b6040516001600160a01b0383166024820152604481018290526110a190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526113c1565b60006111c88484610e2f565b90506000198114610fc457818110156111e057600080fd5b610fc48484848403610ff1565b6110a1600080fd5b6005546001600160a01b0316331461093757600080fd5b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008061127f6112766005546001600160a01b031690565b8787878761143d565b9050600061128c82610d50565b90506112988882611762565b979650505050505050565b804710156112b057600080fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146112fd576040519150601f19603f3d011682016040523d82523d6000602084013e611302565b606091505b50509050806110a157600080fd5b600061087b826001015490565b60008382101561132e576000611330565b825b949350505050565b60006113448585611f35565b61134e8584611802565b6113588785611802565b6113629190611f35565b61136c9085611efc565b610d479190611f13565b8083600101600082825461138a9190611ed0565b90915550506001600160a01b038216600090815260208490526040812080548392906113b7908490611ed0565b9091555050505050565b6000611416826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661181d9092919063ffffffff16565b8051909150156110a157808060200190518101906114349190611f48565b6110a157600080fd5b600034156114d3576040516bffffffffffffffffffffffff197f0000000000000000000000000000000000000000000000000000000000000000606090811b8216602084015261017760eb1b60348401527f0000000000000000000000000000000000000000000000000000000000000000901b166037820152349550604b01604051602081830303815290604052915061152f565b81511561152f577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661151c601484516115159190611f35565b849061182c565b6001600160a01b03161461152f57600080fd5b6000198310156115f75781516000036115535761154c8584611856565b94506115f7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632f80bb1d61158b8461186c565b856040518363ffffffff1660e01b81526004016115a9929190611f6a565b6020604051808303816000875af19250505080156115e4575060408051601f3d908101601f191682019092526115e191810190611ee3565b60015b156115f7576115f38682611856565b9550505b34158015611606575060008251115b15611652576000611617838261182c565b905061162581333089611950565b611650817f000000000000000000000000000000000000000000000000000000000000000088611988565b505b815160000361168e576116877f0000000000000000000000000000000000000000000000000000000000000000338888611950565b5083610d47565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663c04b8d5934156116c957866116cc565b60005b6040518060a001604052808681526020018a6001600160a01b03168152602001428152602001898152602001888152506040518363ffffffff1660e01b81526004016117189190611f8c565b60206040518083038185885af1158015611736573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061175b9190611ee3565b9050610d47565b61176c8282611a3b565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156117d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f49190611ee3565b60025411156109f457600080fd5b6000828210156118135760006108fc565b6108fc8383611f35565b60606113308484600085611ad7565b6000611839826014611ed0565b8351101561184657600080fd5b500160200151600160601b900490565b600081831061186557816108fc565b5090919050565b606060006017601484516118809190611f35565b61188a9190611f13565b9050600083516001600160401b038111156118a7576118a7611cd6565b6040519080825280601f01601f1916602001820160405280156118d1576020820181803683370190505b5090506017820260005b811561192957601d82018601516901000000000000000000600160e81b03811660181b602083018501526001600160e81b0319811660348301850152506017820391506017810190506118db565b6bffffffffffffffffffffffff196020870151166020820184015250508092505050919050565b6040516001600160a01b0380851660248301528316604482015260648101829052610fc49085906323b872dd60e01b90608401611185565b801580611a025750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156119dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a009190611ee3565b155b611a0b57600080fd5b6040516001600160a01b0383166024820152604481018290526110a190849063095ea7b360e01b90606401611185565b6001600160a01b038216611a4e57600080fd5b8060026000828254611a609190611ed0565b90915550506001600160a01b03821660009081526020819052604081208054839290611a8d908490611ed0565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b606082471015611ae657600080fd5b6001600160a01b0385163b611afa57600080fd5b600080866001600160a01b03168587604051611b169190611fe4565b60006040518083038185875af1925050503d8060008114611b53576040519150601f19603f3d011682016040523d82523d6000602084013e611b58565b606091505b509150915061129882828660608315611b725750816108fc565b8251156102255782518084602001fd5b60005b83811015611b9d578181015183820152602001611b85565b50506000910152565b60008151808452611bbe816020860160208601611b82565b601f01601f19169290920160200192915050565b6020815260006108fc6020830184611ba6565b6001600160a01b0381168114610fee57600080fd5b60008060408385031215611c0d57600080fd5b8235611c1881611be5565b946020939093013593505050565b600060208284031215611c3857600080fd5b81356108fc81611be5565b600080600060608486031215611c5857600080fd5b8335611c6381611be5565b92506020840135611c7381611be5565b929592945050506040919091013590565b60008060408385031215611c9757600080fd5b8235611ca281611be5565b91506020830135611cb281611be5565b809150509250929050565b600060208284031215611ccf57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112611cfd57600080fd5b81356001600160401b0380821115611d1757611d17611cd6565b604051601f8301601f19908116603f01168101908282118183101715611d3f57611d3f611cd6565b81604052838152866020858801011115611d5857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060808587031215611d8e57600080fd5b8435611d9981611be5565b9350602085013592506040850135915060608501356001600160401b03811115611dc257600080fd5b611dce87828801611cec565b91505092959194509250565b600080600080600060a08688031215611df257600080fd5b8535611dfd81611be5565b94506020860135611e0d81611be5565b9350604086013592506060860135915060808601356001600160401b03811115611e3657600080fd5b611e4288828901611cec565b9150509295509295909350565b60008060408385031215611e6257600080fd5b8235915060208301356001600160401b0381168114611cb257600080fd5b600181811c90821680611e9457607f821691505b602082108103611eb457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561087b5761087b611eba565b600060208284031215611ef557600080fd5b5051919050565b808202811582820484141761087b5761087b611eba565b600082611f3057634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561087b5761087b611eba565b600060208284031215611f5a57600080fd5b815180151581146108fc57600080fd5b604081526000611f7d6040830185611ba6565b90508260208301529392505050565b602081526000825160a06020840152611fa860c0840182611ba6565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b60008251611ff6818460208701611b82565b919091019291505056fea26469706673582212200c3c6565315928ce37e053a4badba7403483306e3c24cc2ee709880218cfbaf364736f6c63430008110033000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec3000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000632cdae00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006372c87000000000000000000000000000000000000000000000000000000000004f1a000000000000000000000000000000000000000000000000000000000000ed4e00000000000000000000000000000000000000000000000043c33c193756480000
Deployed Bytecode
0x6080604052600436106102255760003560e01c806393e2265911610123578063ad5c4648116100ab578063dd62ed3e1161006f578063dd62ed3e14610737578063e33b7de314610757578063edde41b21461076c578063f2fde38b14610781578063fc0c546a146107a157600080fd5b8063ad5c46481461067c578063b2adf0cc146106b0578063b5ddd347146106e4578063ba4d0c99146106f7578063cc71fadf1461071757600080fd5b8063a3f8eace116100f2578063a3f8eace146105d3578063a457c2d7146105f3578063a8dd07dc14610613578063a9059cbb14610628578063ab0bcc411461064857600080fd5b806393e226591461055757806395d89b411461058b5780639852595c146105a05780639e48ff5a146105c057600080fd5b806339509351116101b15780638078059c116101755780638078059c14610491578063837971e4146104c557806389a30271146104e55780638da5cb5b146105195780639097548d1461053757600080fd5b806339509351146103a45780634db4a352146103c457806370a0823114610410578063715018a614610446578063735de9f71461045d57600080fd5b806318160ddd116101f857806318160ddd146102ff578063191655871461031457806323b872dd14610334578063254800d414610354578063313ce5671461038857600080fd5b806306fdde031461022a578063095ea7b3146102555780631283e3281461028557806313d033c0146102b3575b600080fd5b34801561023657600080fd5b5061023f6107d5565b60405161024c9190611bd2565b60405180910390f35b34801561026157600080fd5b50610275610270366004611bfa565b610867565b604051901515815260200161024c565b34801561029157600080fd5b506102a56102a0366004611c26565b610881565b60405190815260200161024c565b3480156102bf57600080fd5b506102e77f0000000000000000000000000000000000000000000000000000000063c1e27081565b6040516001600160401b03909116815260200161024c565b34801561030b57600080fd5b506002546102a5565b34801561032057600080fd5b506102a561032f366004611c26565b61088e565b34801561034057600080fd5b5061027561034f366004611c43565b6108dd565b34801561036057600080fd5b506102e77f000000000000000000000000000000000000000000000000000000006372c87081565b34801561039457600080fd5b506040516012815260200161024c565b3480156103b057600080fd5b506102756103bf366004611bfa565b610903565b3480156103d057600080fd5b506103f87f000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab681565b6040516001600160a01b03909116815260200161024c565b34801561041c57600080fd5b506102a561042b366004611c26565b6001600160a01b031660009081526020819052604090205490565b34801561045257600080fd5b5061045b610925565b005b34801561046957600080fd5b506103f87f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156481565b34801561049d57600080fd5b506102e77f000000000000000000000000000000000000000000000000ffffffffffffffff81565b3480156104d157600080fd5b5061045b6104e0366004611c84565b610939565b3480156104f157600080fd5b506103f87f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b34801561052557600080fd5b506005546001600160a01b03166103f8565b34801561054357600080fd5b506102a5610552366004611cbd565b6109f8565b34801561056357600080fd5b506102e77f000000000000000000000000000000000000000000000000000000006460167081565b34801561059757600080fd5b5061023f610a3c565b3480156105ac57600080fd5b506102a56105bb366004611c26565b610a4b565b6102a56105ce366004611d78565b610a58565b3480156105df57600080fd5b506102a56105ee366004611c26565b610be9565b3480156105ff57600080fd5b5061027561060e366004611bfa565b610c35565b34801561061f57600080fd5b506102a5610c6a565b34801561063457600080fd5b50610275610643366004611bfa565b610c7b565b34801561065457600080fd5b506102e77f00000000000000000000000000000000000000000000000000000000632cdae081565b34801561068857600080fd5b506103f87f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b3480156106bc57600080fd5b506102a57f000000000000000000000000000000000000000000000043c33c19375648000081565b6102a56106f2366004611dda565b610c89565b34801561070357600080fd5b506102a5610712366004611cbd565b610d50565b34801561072357600080fd5b506102a5610732366004611e4f565b610d8a565b34801561074357600080fd5b506102a5610752366004611c84565b610e2f565b34801561076357600080fd5b506102a5610e5a565b34801561077857600080fd5b5061045b610e66565b34801561078d57600080fd5b5061045b61079c366004611c26565b610fca565b3480156107ad57600080fd5b506103f87f0000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec381565b6060600380546107e490611e80565b80601f016020809104026020016040519081016040528092919081815260200182805461081090611e80565b801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b5050505050905090565b600033610875818585610ff1565b60019150505b92915050565b600061087b600883611078565b60008061089a83610be9565b90506108a860068483611096565b6108b283826110a6565b61087b7f0000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec38483611159565b6000336108eb8582856111bc565b6108f68585856111ed565b60019150505b9392505050565b6000336108758185856109168383610e2f565b6109209190611ed0565b610ff1565b61092d6111f5565b610937600061120c565b565b6109416111f5565b816001600160a01b03167f0000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec36001600160a01b03160361097f57600080fd5b6040516370a0823160e01b81523060048201526109f490839083906001600160a01b038316906370a0823190602401602060405180830381865afa1580156109cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ef9190611ee3565b611159565b5050565b60006c0c9f2c9cd04674edea40000000610a327f000000000000000000000000000000000000000000000000008e1bc9bf04000084611efc565b61087b9190611f13565b6060600480546107e490611e80565b600061087b600683611078565b60007f00000000000000000000000000000000000000000000000000000000632cdae06001600160401b03164210158015610abb57507f000000000000000000000000000000000000000000000000ffffffffffffffff6001600160401b031642105b610ac457600080fd5b6000610acf60025490565b6040516370a0823160e01b81523060048201527f0000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec36001600160a01b0316906370a0823190602401602060405180830381865afa158015610b33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b579190611ee3565b610b619190611f35565b905060008111610b7057600080fd5b6000610b87878787610b81866109f8565b8861125e565b905081811480610bb757507f000000000000000000000000000000000000000000000043c33c1937564800008110155b610bc057600080fd5b600034118015610bd05750600047115b15610bdf57610bdf33476112a3565b9695505050505050565b600080610bf583610a4b565b905080610c2b82610c1b866001600160a01b031660009081526020819052604090205490565b610c259190611ed0565b42610d8a565b6108fc9190611f35565b60003381610c438286610e2f565b905083811015610c5257600080fd5b610c5f8286868403610ff1565b506001949350505050565b6000610c766008611310565b905090565b6000336108758185856111ed565b600080610c9887868686610a58565b9050610cbe876064610cab846005611efc565b610cb59190611f13565b60089190611096565b610ccf866064610cab84600f611efc565b6001600160a01b038088169087167f08f13de638226119399e648639b1cce10d5af6854de598546e09cee33e0fdbcc6064610d0b85600f611efc565b610d159190611f13565b6064610d22866005611efc565b610d2c9190611f13565b6040805192835260208301919091520160405180910390a390505b95945050505050565b60007f000000000000000000000000000000000000000000000000008e1bc9bf040000610a32836c0c9f2c9cd04674edea40000000611efc565b60006108fc7f000000000000000000000000000000000000000000000000000000006372c8706001600160401b03167f00000000000000000000000000000000000000000000000000000000646016706001600160401b0316610e207f0000000000000000000000000000000000000000000000000000000063c1e2706001600160401b031687876001600160401b031661131d565b856001600160401b0316611338565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6000610c766006611310565b7f000000000000000000000000000000000000000000000000ffffffffffffffff6001600160401b0316421015610e9c57600080fd5b7f0000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec36001600160a01b03166342966c68610ed460025490565b610edc610e5a565b6040516370a0823160e01b81523060048201527f0000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec36001600160a01b0316906370a0823190602401602060405180830381865afa158015610f40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f649190611ee3565b610f6e9190611ed0565b610f789190611f35565b6040518263ffffffff1660e01b8152600401610f9691815260200190565b600060405180830381600087803b158015610fb057600080fd5b505af1158015610fc4573d6000803e3d6000fd5b50505050565b610fd26111f5565b6001600160a01b038116610fe557600080fd5b610fee8161120c565b50565b6001600160a01b03831661100457600080fd5b6001600160a01b03821661101757600080fd5b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0381166000908152602083905260408120546108fc565b6110a1838383611376565b505050565b6001600160a01b0382166110b957600080fd5b6001600160a01b038216600090815260208190526040902054818110156110df57600080fd5b6001600160a01b038316600090815260208190526040812083830390556002805484929061110e908490611f35565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b6040516001600160a01b0383166024820152604481018290526110a190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526113c1565b60006111c88484610e2f565b90506000198114610fc457818110156111e057600080fd5b610fc48484848403610ff1565b6110a1600080fd5b6005546001600160a01b0316331461093757600080fd5b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008061127f6112766005546001600160a01b031690565b8787878761143d565b9050600061128c82610d50565b90506112988882611762565b979650505050505050565b804710156112b057600080fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146112fd576040519150601f19603f3d011682016040523d82523d6000602084013e611302565b606091505b50509050806110a157600080fd5b600061087b826001015490565b60008382101561132e576000611330565b825b949350505050565b60006113448585611f35565b61134e8584611802565b6113588785611802565b6113629190611f35565b61136c9085611efc565b610d479190611f13565b8083600101600082825461138a9190611ed0565b90915550506001600160a01b038216600090815260208490526040812080548392906113b7908490611ed0565b9091555050505050565b6000611416826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661181d9092919063ffffffff16565b8051909150156110a157808060200190518101906114349190611f48565b6110a157600080fd5b600034156114d3576040516bffffffffffffffffffffffff197f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2606090811b8216602084015261017760eb1b60348401527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48901b166037820152349550604b01604051602081830303815290604052915061152f565b81511561152f577f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486001600160a01b031661151c601484516115159190611f35565b849061182c565b6001600160a01b03161461152f57600080fd5b6000198310156115f75781516000036115535761154c8584611856565b94506115f7565b7f000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab66001600160a01b0316632f80bb1d61158b8461186c565b856040518363ffffffff1660e01b81526004016115a9929190611f6a565b6020604051808303816000875af19250505080156115e4575060408051601f3d908101601f191682019092526115e191810190611ee3565b60015b156115f7576115f38682611856565b9550505b34158015611606575060008251115b15611652576000611617838261182c565b905061162581333089611950565b611650817f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156488611988565b505b815160000361168e576116877f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48338888611950565b5083610d47565b6001600160a01b037f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615641663c04b8d5934156116c957866116cc565b60005b6040518060a001604052808681526020018a6001600160a01b03168152602001428152602001898152602001888152506040518363ffffffff1660e01b81526004016117189190611f8c565b60206040518083038185885af1158015611736573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061175b9190611ee3565b9050610d47565b61176c8282611a3b565b6040516370a0823160e01b81523060048201527f0000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec36001600160a01b0316906370a0823190602401602060405180830381865afa1580156117d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f49190611ee3565b60025411156109f457600080fd5b6000828210156118135760006108fc565b6108fc8383611f35565b60606113308484600085611ad7565b6000611839826014611ed0565b8351101561184657600080fd5b500160200151600160601b900490565b600081831061186557816108fc565b5090919050565b606060006017601484516118809190611f35565b61188a9190611f13565b9050600083516001600160401b038111156118a7576118a7611cd6565b6040519080825280601f01601f1916602001820160405280156118d1576020820181803683370190505b5090506017820260005b811561192957601d82018601516901000000000000000000600160e81b03811660181b602083018501526001600160e81b0319811660348301850152506017820391506017810190506118db565b6bffffffffffffffffffffffff196020870151166020820184015250508092505050919050565b6040516001600160a01b0380851660248301528316604482015260648101829052610fc49085906323b872dd60e01b90608401611185565b801580611a025750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156119dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a009190611ee3565b155b611a0b57600080fd5b6040516001600160a01b0383166024820152604481018290526110a190849063095ea7b360e01b90606401611185565b6001600160a01b038216611a4e57600080fd5b8060026000828254611a609190611ed0565b90915550506001600160a01b03821660009081526020819052604081208054839290611a8d908490611ed0565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b606082471015611ae657600080fd5b6001600160a01b0385163b611afa57600080fd5b600080866001600160a01b03168587604051611b169190611fe4565b60006040518083038185875af1925050503d8060008114611b53576040519150601f19603f3d011682016040523d82523d6000602084013e611b58565b606091505b509150915061129882828660608315611b725750816108fc565b8251156102255782518084602001fd5b60005b83811015611b9d578181015183820152602001611b85565b50506000910152565b60008151808452611bbe816020860160208601611b82565b601f01601f19169290920160200192915050565b6020815260006108fc6020830184611ba6565b6001600160a01b0381168114610fee57600080fd5b60008060408385031215611c0d57600080fd5b8235611c1881611be5565b946020939093013593505050565b600060208284031215611c3857600080fd5b81356108fc81611be5565b600080600060608486031215611c5857600080fd5b8335611c6381611be5565b92506020840135611c7381611be5565b929592945050506040919091013590565b60008060408385031215611c9757600080fd5b8235611ca281611be5565b91506020830135611cb281611be5565b809150509250929050565b600060208284031215611ccf57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112611cfd57600080fd5b81356001600160401b0380821115611d1757611d17611cd6565b604051601f8301601f19908116603f01168101908282118183101715611d3f57611d3f611cd6565b81604052838152866020858801011115611d5857600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060808587031215611d8e57600080fd5b8435611d9981611be5565b9350602085013592506040850135915060608501356001600160401b03811115611dc257600080fd5b611dce87828801611cec565b91505092959194509250565b600080600080600060a08688031215611df257600080fd5b8535611dfd81611be5565b94506020860135611e0d81611be5565b9350604086013592506060860135915060808601356001600160401b03811115611e3657600080fd5b611e4288828901611cec565b9150509295509295909350565b60008060408385031215611e6257600080fd5b8235915060208301356001600160401b0381168114611cb257600080fd5b600181811c90821680611e9457607f821691505b602082108103611eb457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561087b5761087b611eba565b600060208284031215611ef557600080fd5b5051919050565b808202811582820484141761087b5761087b611eba565b600082611f3057634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561087b5761087b611eba565b600060208284031215611f5a57600080fd5b815180151581146108fc57600080fd5b604081526000611f7d6040830185611ba6565b90508260208301529392505050565b602081526000825160a06020840152611fa860c0840182611ba6565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b60008251611ff6818460208701611b82565b919091019291505056fea26469706673582212200c3c6565315928ce37e053a4badba7403483306e3c24cc2ee709880218cfbaf364736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec3000000000000000000000000000000000000000000000000008e1bc9bf04000000000000000000000000000000000000000000000000000000000000632cdae00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006372c87000000000000000000000000000000000000000000000000000000000004f1a000000000000000000000000000000000000000000000000000000000000ed4e00000000000000000000000000000000000000000000000043c33c193756480000
-----Decoded View---------------
Arg [0] : uniswapRouter_ (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564
Arg [1] : uniswapQuoter_ (address): 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6
Arg [2] : USDC_ (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [3] : token_ (address): 0x2707293FFa6593287ecd06db64125Ade687B6eC3
Arg [4] : rate_ (uint256): 40000000000000000
Arg [5] : saleStart_ (uint64): 1663884000
Arg [6] : saleDuration_ (uint64): 0
Arg [7] : vestingStart_ (uint64): 1668466800
Arg [8] : cliffDuration_ (uint64): 5184000
Arg [9] : vestingDuration_ (uint64): 15552000
Arg [10] : buyInMinimum_ (uint256): 1250000000000000000000
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Arg [1] : 000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6
Arg [2] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [3] : 0000000000000000000000002707293ffa6593287ecd06db64125ade687b6ec3
Arg [4] : 000000000000000000000000000000000000000000000000008e1bc9bf040000
Arg [5] : 00000000000000000000000000000000000000000000000000000000632cdae0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 000000000000000000000000000000000000000000000000000000006372c870
Arg [8] : 00000000000000000000000000000000000000000000000000000000004f1a00
Arg [9] : 0000000000000000000000000000000000000000000000000000000000ed4e00
Arg [10] : 000000000000000000000000000000000000000000000043c33c193756480000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.