BangerV4
0x00000000cdab5161815cd4005fac11ac3a796f63
Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
17,727 bytes
ABI entries
43
17 read · 18 write
License
none
Contract information
- Address
- 0x00000000cdab5161815cd4005fac11ac3a796f63
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.26+commit.8a97fa7a
- Optimization
- Enabled
- Creator
- 0x4e59b44847…26c0B4956C
- Creation tx
- 0x5be10b444f…e82a625ad0
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (17)
bundleFeeSwitch() → bool
defaultLockingPeriod() → uint64
deprecated() → bool
fee() → uint24
generateSalt(address, uint256, string, string, string, string, address, string, uint256) → bytes32, address
liquidityLocker() → address
lpFeesCut() → uint8
owner() → address
positionManager() → address
predictToken(address, uint256, string, string, string, string, address, string, uint256, bytes32) → address
protocolCut() → uint8
supportsInterface(bytes4) → bool
swapRouter() → address
taxCollector() → address
taxRate() → uint8
uniswapV3Factory() → address
weth() → address
Events (2)
OwnershipTransferredTokenCreated
ABI
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "Deprecated",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"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": false,
"internalType": "address",
"name": "tokenAddress",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "lpNftId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "deployer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "fid",
"type": "uint256"
},
{
"indexed": false,
"internalType": "string",
"name": "name",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "supply",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "lockerAddress",
"type": "address"
},
{
"indexed": false,
"internalType": "string",
"name": "extraStringData",
"type": "string"
},
{
"indexed": false,
"internalType": "bool",
"name": "isMsgSenderOwner",
"type": "bool"
}
],
"name": "TokenCreated",
"type": "event"
},
{
"stateMutability": "payable",
"type": "fallback"
},
{
"inputs": [],
"name": "bundleFeeSwitch",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "defaultLockingPeriod",
"outputs": [
{
"internalType": "uint64",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_supply",
"type": "uint256"
},
{
"internalType": "int24",
"name": "_initialTick",
"type": "int24"
},
{
"internalType": "bytes32",
"name": "_salt",
"type": "bytes32"
},
{
"internalType": "address",
"name": "_deployer",
"type": "address"
},
{
"internalType": "uint256",
"name": "_fid",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "mintPrice",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "mintEndTimestamp",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxMintSupply",
"type": "uint256"
},
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "string",
"name": "_symbol",
"type": "string"
},
{
"internalType": "string",
"name": "_image",
"type": "string"
},
{
"internalType": "string",
"name": "_animation",
"type": "string"
},
{
"internalType": "address",
"name": "_metadataAddress",
"type": "address"
},
{
"internalType": "string",
"name": "_extraStringData",
"type": "string"
}
],
"name": "deployToken",
"outputs": [
{
"internalType": "contract BangerV4Token",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "deprecated",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fee",
"outputs": [
{
"internalType": "uint24",
"name": "",
"type": "uint24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "deployer",
"type": "address"
},
{
"internalType": "uint256",
"name": "fid",
"type": "uint256"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "string",
"name": "image",
"type": "string"
},
{
"internalType": "string",
"name": "animation",
"type": "string"
},
{
"internalType": "address",
"name": "metadataAddress",
"type": "address"
},
{
"internalType": "string",
"name": "extraStringData",
"type": "string"
},
{
"internalType": "uint256",
"name": "supply",
"type": "uint256"
}
],
"name": "generateSalt",
"outputs": [
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint24",
"name": "_fee",
"type": "uint24"
}
],
"name": "initialSwapTokens",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "liquidityLocker",
"outputs": [
{
"internalType": "contract ILockerFactoryV3",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "lpFeesCut",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "quantity",
"type": "uint256"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "uint256[]",
"name": "ids",
"type": "uint256[]"
},
{
"internalType": "uint256[]",
"name": "values",
"type": "uint256[]"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "onERC1155BatchReceived",
"outputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "onERC1155Received",
"outputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "positionManager",
"outputs": [
{
"internalType": "contract INonfungiblePositionManager",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "deployer",
"type": "address"
},
{
"internalType": "uint256",
"name": "fid",
"type": "uint256"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "string",
"name": "image",
"type": "string"
},
{
"internalType": "string",
"name": "animation",
"type": "string"
},
{
"internalType": "address",
"name": "metadataAddress",
"type": "address"
},
{
"internalType": "string",
"name": "extraStringData",
"type": "string"
},
{
"internalType": "uint256",
"name": "supply",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
}
],
"name": "predictToken",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "protocolCut",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "_deprecated",
"type": "bool"
}
],
"name": "setDeprecated",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "swapRouter",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "taxCollector",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "taxRate",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "_enabled",
"type": "bool"
}
],
"name": "toggleBundleFeeSwitch",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "uniswapV3Factory",
"outputs": [
{
"internalType": "contract IUniswapV3Factory",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint64",
"name": "newPeriod",
"type": "uint64"
}
],
"name": "updateDefaultLockingPeriod",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newLocker",
"type": "address"
}
],
"name": "updateLiquidityLocker",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newPositionManager",
"type": "address"
}
],
"name": "updatePositionManager",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint8",
"name": "newFee",
"type": "uint8"
}
],
"name": "updateProtocolFees",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newRouter",
"type": "address"
}
],
"name": "updateSwapRouter",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newCollector",
"type": "address"
}
],
"name": "updateTaxCollector",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint8",
"name": "newRate",
"type": "uint8"
}
],
"name": "updateTaxRate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newFactory",
"type": "address"
}
],
"name": "updateUniV3Factory",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newWeth",
"type": "address"
}
],
"name": "updateWeth",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "weth",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {TickMath} from "@uniswap/v3-core/contracts/libraries/TickMath.sol";
import {IERC1155Receiver} from "@openzeppelin/contracts/interfaces/IERC1155Receiver.sol";
import {INet} from "../INet.sol";
import {IStorage} from "../IStorage.sol";
import {IInscribedDropsDynamic} from "../IInscribedDropsDynamic.sol";
import {INonfungiblePositionManager, IUniswapV3Factory, ILockerFactoryV3, ILocker, ExactInputSingleParams, ISwapRouter} from "../interface.sol";
import {Bytes32AddressLib} from "../Bytes32AddressLib.sol";
import {LibString} from "../LibString.sol";
import {Base64} from "../Base64.sol";
import {BangerV4Token} from "./BangerV4Token.sol";
contract BangerV4 is IERC1155Receiver, Ownable {
using TickMath for int24;
using Bytes32AddressLib for bytes32;
using LibString for address;
using LibString for uint256;
error Deprecated();
event TokenCreated(
address tokenAddress,
uint256 lpNftId,
address deployer,
uint256 fid,
string name,
string symbol,
uint256 supply,
address lockerAddress,
string extraStringData,
bool isMsgSenderOwner
);
address public taxCollector =
address(0x2a67566660714AfaD6eB80A8a64eb7431B121F3c);
uint64 public defaultLockingPeriod = 33275115461;
uint8 public taxRate = 25; // 25 / 1000 -> 2.5 %
uint8 public lpFeesCut = 50; // 5 / 100 -> 5%
uint8 public protocolCut = 30; // 3 / 100 -> 3%
uint24 public fee = 10_000;
ILockerFactoryV3 public liquidityLocker =
ILockerFactoryV3(address(0x00000000a4944d1E707f869356fF4B48e527370f));
address public weth = address(0x4200000000000000000000000000000000000006);
IUniswapV3Factory public uniswapV3Factory =
IUniswapV3Factory(address(0x33128a8fC17869897dcE68Ed026d694621f6FDfD));
INonfungiblePositionManager public positionManager =
INonfungiblePositionManager(
address(0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1)
);
address public swapRouter =
address(0x2626664c2603336E57B271c5C0b26F421741e481);
address internal constant netAddress =
address(0x00000000B24D62781dB359b07880a105cD0b64e6);
address internal constant netStorageAddress =
address(0x00000000DB40fcB9f4466330982372e27Fd7Bbf5);
address internal constant inscribedDropsAddress =
address(0x0000004c6cc2cA10Cf4d67C8902659085D31e1Dc);
bool public deprecated;
bool public bundleFeeSwitch = true;
constructor()
Ownable(address(0xcC4193B652FcB25347Bb44a88d2b09B52585643F))
{}
function deployToken(
uint256 _supply,
int24 _initialTick,
bytes32 _salt,
address _deployer,
uint256 _fid,
uint256 mintPrice,
uint256 mintEndTimestamp,
uint256 maxMintSupply,
string calldata _name,
string calldata _symbol,
string calldata _image,
string calldata _animation,
address _metadataAddress,
string calldata _extraStringData
) external payable returns (BangerV4Token token, uint256 tokenId) {
if (deprecated) revert Deprecated();
int24 tickSpacing = uniswapV3Factory.feeAmountTickSpacing(fee);
require(
tickSpacing != 0 && _initialTick % tickSpacing == 0,
"Invalid tick"
);
token = new BangerV4Token{
salt: keccak256(abi.encode(_deployer, _salt))
}(
_name,
_symbol,
_supply,
_deployer,
_fid,
_image,
_animation,
_metadataAddress,
_extraStringData
);
// Makes sure that the token address is less than the WETH address. This is so that the token
// is first in the pool. Just makes things consistent.
require(address(token) < weth, "Invalid salt");
uint160 sqrtPriceX96 = _initialTick.getSqrtRatioAtTick();
address pool = uniswapV3Factory.createPool(address(token), weth, fee);
IUniswapV3Factory(pool).initialize(sqrtPriceX96);
INonfungiblePositionManager.MintParams
memory params = INonfungiblePositionManager.MintParams(
address(token),
weth,
fee,
_initialTick,
maxUsableTick(tickSpacing),
_supply,
0,
0,
0,
address(this),
block.timestamp
);
token.approve(address(positionManager), _supply);
(tokenId, , , ) = positionManager.mint(params);
address lockerAddress = liquidityLocker.deploy(
address(positionManager),
_deployer,
defaultLockingPeriod,
tokenId,
lpFeesCut,
address(positionManager)
);
positionManager.safeTransferFrom(address(this), lockerAddress, tokenId);
ILocker(lockerAddress).initializer(tokenId);
if (msg.value > 0) {
uint256 remainingFundsToBuyTokens = msg.value;
if (bundleFeeSwitch) {
uint256 protocolFees = (msg.value * taxRate) / 1000;
remainingFundsToBuyTokens = msg.value - protocolFees;
(bool success, ) = payable(taxCollector).call{
value: protocolFees
}("");
if (!success) {
revert("Failed to send protocol fees");
}
}
ExactInputSingleParams memory swapParams = ExactInputSingleParams({
tokenIn: weth, // The token we are exchanging from (ETH wrapped as WETH)
tokenOut: address(token), // The token we are exchanging to
fee: fee, // The pool fee
recipient: _deployer, // The recipient address
amountIn: remainingFundsToBuyTokens, // The amount of ETH (WETH) to be swapped
amountOutMinimum: 0, // Minimum amount to receive
sqrtPriceLimitX96: 0 // No price limit
});
// The call to `exactInputSingle` executes the swap.
ISwapRouter(swapRouter).exactInputSingle{
value: remainingFundsToBuyTokens
}(swapParams);
}
// Send Net message
uint256 msgIdx = INet(netAddress).getTotalMessagesCount();
INet(netAddress).sendMessageViaApp(
msg.sender,
string.concat(
"Deployed ",
_name,
" (",
_symbol,
") to ",
address(token).toHexStringChecksumed(),
" (pool: ",
pool.toHexStringChecksumed(),
")"
),
address(token).toHexStringChecksumed(),
// Use encode rather than encodePacked so that the data can be easily decoded
abi.encode(
msgIdx,
pool,
token,
lockerAddress,
tokenId,
_deployer,
_fid,
_extraStringData
)
);
// Create drop
uint256 dropIdx = IInscribedDropsDynamic(inscribedDropsAddress)
.totalDrops();
IInscribedDropsDynamic(inscribedDropsAddress).inscribe(
mintPrice,
maxMintSupply,
mintEndTimestamp,
// No mint limit per wallet because this contract is the minter
// of all tokens and so mint limit would not work with that.
0,
_metadataAddress != address(0)
? ""
: getUri(
_name,
_symbol,
_image,
_animation,
_extraStringData,
address(token)
),
_metadataAddress
);
// Transfer the first minted token to _deployer, which supports if a bot deploys tokens on
// behalf of a user
IInscribedDropsDynamic(inscribedDropsAddress).safeTransferFrom(
address(this),
_deployer,
dropIdx,
1,
""
);
// Map the token address to relevant data
IStorage(netStorageAddress).put(
bytes32(uint256(uint160(address(token)))),
"",
// Use encode rather than encodePacked so that the data can be easily decoded
abi.encode(
msgIdx,
dropIdx,
inscribedDropsAddress,
pool,
lockerAddress,
tokenId
)
);
// Map the drop idx to the message idx and token address
IStorage(netStorageAddress).put(
bytes32(dropIdx),
"",
// Use encode rather than encodePacked so that the data can be easily decoded
abi.encode(dropIdx, token, pool)
);
emit TokenCreated(
address(token),
tokenId,
_deployer,
_fid,
_name,
_symbol,
_supply,
lockerAddress,
_extraStringData,
msg.sender == owner()
);
}
function getUri(
string calldata name,
string calldata symbol,
string calldata image,
string calldata animation,
string calldata extraStringData,
address token
) internal pure returns (string memory) {
return
string.concat(
'{"name":"',
name,
" (",
symbol,
")",
'","description":"Memecoin-NFT created via Net. Memecoin is located at ',
token.toHexStringChecksumed(),
"\\n\\n",
extraStringData,
'","image":"',
bytes(image).length > 0
? image
: string.concat(
"data:image/svg+xml;base64,",
Base64.encode(
bytes(
string.concat(
'<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" style="background-color:#000"><text x="50%" y="50%" text-anchor="middle" dominant-baseline="middle" style="font-family:monospace;font-size:24px;fill:#0f7">',
name,
"</text></svg>"
)
)
)
),
'","animation_url":"',
animation,
'"}'
);
}
function predictToken(
address deployer,
uint256 fid,
string calldata name,
string calldata symbol,
string calldata image,
string calldata animation,
address metadataAddress,
string calldata extraStringData,
uint256 supply,
bytes32 salt
) public view returns (address) {
bytes32 create2Salt = keccak256(abi.encode(deployer, salt));
return
keccak256(
abi.encodePacked(
bytes1(0xFF),
address(this),
create2Salt,
keccak256(
abi.encodePacked(
type(BangerV4Token).creationCode,
abi.encode(
name,
symbol,
supply,
deployer,
fid,
image,
animation,
metadataAddress,
extraStringData
)
)
)
)
).fromLast20Bytes();
}
function generateSalt(
address deployer,
uint256 fid,
string calldata name,
string calldata symbol,
string calldata image,
string calldata animation,
address metadataAddress,
string calldata extraStringData,
uint256 supply
) external view returns (bytes32 salt, address token) {
for (uint256 i; ; i++) {
salt = bytes32(i);
token = predictToken(
deployer,
fid,
name,
symbol,
image,
animation,
metadataAddress,
extraStringData,
supply,
salt
);
if (token < weth && token.code.length == 0) {
break;
}
}
}
function toggleBundleFeeSwitch(bool _enabled) external onlyOwner {
bundleFeeSwitch = _enabled;
}
function setDeprecated(bool _deprecated) external onlyOwner {
deprecated = _deprecated;
}
function updateTaxCollector(address newCollector) external onlyOwner {
taxCollector = newCollector;
}
function updateLiquidityLocker(address newLocker) external onlyOwner {
liquidityLocker = ILockerFactoryV3(newLocker);
}
function updatePositionManager(
address newPositionManager
) external onlyOwner {
positionManager = INonfungiblePositionManager(newPositionManager);
}
function updateUniV3Factory(address newFactory) external onlyOwner {
uniswapV3Factory = IUniswapV3Factory(newFactory);
}
function updateSwapRouter(address newRouter) external onlyOwner {
swapRouter = newRouter;
}
function updateWeth(address newWeth) external onlyOwner {
weth = newWeth;
}
function updateDefaultLockingPeriod(uint64 newPeriod) external onlyOwner {
defaultLockingPeriod = newPeriod;
}
function updateProtocolFees(uint8 newFee) external onlyOwner {
lpFeesCut = newFee;
}
function updateTaxRate(uint8 newRate) external onlyOwner {
taxRate = newRate;
}
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
function supportsInterface(
bytes4 interfaceId
) external view returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId;
}
fallback() external payable {}
receive() external payable {}
function mint(address token, uint256 quantity) external payable {
// Get the message index and drop index
(, bytes memory tokenData) = IStorage(netStorageAddress).get(
bytes32(uint256(uint160(token))),
address(this)
);
// We know tokenData consists of uint256, uint256, address, address, address, uint256 so we can unpack them
(, uint256 dropIdx, address readDropsAddress, address pool, , ) = abi
.decode(
tokenData,
(uint256, uint256, address, address, address, uint256)
);
// Mint NFTs
// NOTE: we use readDropsAddress to future-proof this contract in case the inscribedDropsAddress changes
IInscribedDropsDynamic(readDropsAddress).mint{value: msg.value}(
dropIdx,
quantity
);
// Transfer NFTs to msg.sender
IInscribedDropsDynamic(readDropsAddress).safeTransferFrom(
address(this),
msg.sender,
dropIdx,
quantity,
""
);
// Send mint message
INet(netAddress).sendMessageViaApp(
msg.sender,
"mint",
address(token).toHexStringChecksumed(),
// Use encode rather than encodePacked so that the data can be easily decoded
abi.encode(quantity, dropIdx, token, pool)
);
// Use ETH to purchase tokens if value is greater than 0
if (msg.value > 0) {
uint256 amountIn = msg.value -
(IInscribedDropsDynamic(inscribedDropsAddress).feeBps() *
msg.value) /
10_000;
ExactInputSingleParams memory swapParams = ExactInputSingleParams({
tokenIn: weth, // The token we are exchanging from (ETH wrapped as WETH)
tokenOut: address(token), // The token we are exchanging to
fee: fee, // The pool fee
recipient: msg.sender, // The recipient address
amountIn: amountIn, // The amount of ETH (WETH) to be swapped
amountOutMinimum: 0, // Minimum amount of DAI to receive
sqrtPriceLimitX96: 0 // No price limit
});
// The call to `exactInputSingle` executes the swap.
ISwapRouter(swapRouter).exactInputSingle{value: amountIn}(
swapParams
);
}
}
function initialSwapTokens(address token, uint24 _fee) external payable {
ExactInputSingleParams memory swapParams = ExactInputSingleParams({
tokenIn: weth, // The token we are exchanging from (ETH wrapped as WETH)
tokenOut: token, // The token we are exchanging to
fee: _fee, // The pool fee
recipient: msg.sender, // The recipient address
amountIn: msg.value, // The amount of ETH (WETH) to be swapped
amountOutMinimum: 0, // Minimum amount to receive
sqrtPriceLimitX96: 0 // No price limit
});
// The call to `exactInputSingle` executes the swap.
ISwapRouter(swapRouter).exactInputSingle{value: msg.value}(swapParams);
}
}
/// @notice Given a tickSpacing, compute the maximum usable tick
function maxUsableTick(int24 tickSpacing) pure returns (int24) {
unchecked {
return (TickMath.MAX_TICK / tickSpacing) * tickSpacing;
}
}
Chain explorer3401msChain node97ms