BIMOImmutableLaunchVault
0x608c492ac2fd2d488b6ad4defc2bf821ae4d8f95
Verification
Verified
v0.8.24+commit.e11b9ed9
Type
Contract
14,383 bytes
ABI entries
110
53 read · 14 write
License
none
Contract information
- Address
- 0x608c492ac2fd2d488b6ad4defc2bf821ae4d8f95
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.24+commit.e11b9ed9
- Optimization
- Enabled
- Creator
- 0xBD556B6244…EE291dF893
- Creation tx
- 0xa4afcd6b1d…4f4dd8f609
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (53)
BATCH_BIMO() → uint256
BATCH_ETH() → uint256
BATCH_SIZE() → uint256
FISSION_AMOUNT_PER_ADDRESS() → uint256
FISSION_AMOUNT_PER_UNIT() → uint256
LAUNCH_INVENTORY() → uint256
LP_BIMO_PER_UNIT() → uint256
LP_PRICE_PER_UNIT() → uint256
MAX_FISSION_RECIPIENTS_PER_CALL() → uint256
MAX_MINTS_PER_TRANSACTION() → uint8
MAX_MINTS_PER_WALLET() → uint256
MAX_MINT_UNITS() → uint256
MINTER_AMOUNT_PER_UNIT() → uint256
MINT_DURATION() → uint256
PROJECT_RESERVE() → uint256
TOTAL_SUPPLY() → uint256
active() → bool
addLiquidityExecutionReward() → uint256
addLiquidityRewardPaid(uint256) → bool
airdropVault() → address
availableFullBatches() → uint256
availableLiquidityBatches() → uint256
bSingleSigner() → address
bimo() → address
buybackExecutionReward() → uint256
coordinator() → address
deployer() → address
finalPartialBatchReleased() → bool
finalized() → bool
fissionBimoDistributed() → uint256
fissionBimoFinalized() → uint256
fissionBimoReserved() → uint256
fissionExecutionRewardPerRecipient() → uint256
fissionFinalized() → bool
fissionSlotsCreated() → uint256
fissionSlotsDistributed() → uint256
freeInventory() → uint256
freeInventoryFinalized() → uint256
hook() → address
locker() → address
lpEthReserved() → uint256
mintEnd() → uint256
operationsFeePerUnit() → uint256
operationsReserve() → uint256
pendingFissionBimo() → uint256
pendingLiquidityBimo() → uint256
processedFullBatches() → uint256
processedUnits() → uint256
settleFinalPartialLiquidityExecutionReward()
totalExecutionRewardsPaid() → uint256
totalMintedUnits() → uint256
totalOperationsFeesCollected() → uint256
walletMints(address) → uint256
Events (16)
ActivatedBatchReadyConfiguredExecutionRewardPaidFinalPartialBatchReleasedFinalizedFissionDistributedFissionSlotsReservedFreeInventoryBurnedFreeInventorySentToAirdropVaultFreeInventorySentToBFullBatchReleasedMintedUnclaimedFissionFinalizedUnexpectedEthSweptUnusedOperationsReserveSwept
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "bimo_",
"type": "address"
},
{
"internalType": "address",
"name": "bSingleSigner_",
"type": "address"
},
{
"internalType": "address",
"name": "airdropVault_",
"type": "address"
},
{
"internalType": "address",
"name": "hook_",
"type": "address"
},
{
"internalType": "address",
"name": "deployer_",
"type": "address"
},
{
"internalType": "uint256",
"name": "operationsFeePerUnit_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "addLiquidityExecutionReward_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "fissionExecutionRewardPerRecipient_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "buybackExecutionReward_",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AlreadyFinalized",
"type": "error"
},
{
"inputs": [],
"name": "DirectEthDisabled",
"type": "error"
},
{
"inputs": [],
"name": "FinalPartialUnavailable",
"type": "error"
},
{
"inputs": [],
"name": "FissionAlreadyFinalized",
"type": "error"
},
{
"inputs": [],
"name": "FissionBatchTooLarge",
"type": "error"
},
{
"inputs": [],
"name": "FissionNotFinalized",
"type": "error"
},
{
"inputs": [],
"name": "FissionSlotsExceeded",
"type": "error"
},
{
"inputs": [],
"name": "IncorrectPayment",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientFreeInventory",
"type": "error"
},
{
"inputs": [],
"name": "InvalidAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidConfiguration",
"type": "error"
},
{
"inputs": [],
"name": "InvalidFissionRecipient",
"type": "error"
},
{
"inputs": [],
"name": "InvalidQuantity",
"type": "error"
},
{
"inputs": [],
"name": "InventoryNotFunded",
"type": "error"
},
{
"inputs": [],
"name": "MintClosed",
"type": "error"
},
{
"inputs": [],
"name": "MintLimitExceeded",
"type": "error"
},
{
"inputs": [],
"name": "NoFullBatchAvailable",
"type": "error"
},
{
"inputs": [],
"name": "NotActive",
"type": "error"
},
{
"inputs": [],
"name": "NotFinalizable",
"type": "error"
},
{
"inputs": [],
"name": "OperationAlreadyRewarded",
"type": "error"
},
{
"inputs": [],
"name": "OutOfOrderBatch",
"type": "error"
},
{
"inputs": [],
"name": "Reentrancy",
"type": "error"
},
{
"inputs": [],
"name": "SoldOut",
"type": "error"
},
{
"inputs": [],
"name": "TokenCallFailed",
"type": "error"
},
{
"inputs": [],
"name": "Unauthorized",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "mintEnd",
"type": "uint256"
}
],
"name": "Activated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "batchId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "units",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ethAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "bimoAmount",
"type": "uint256"
}
],
"name": "BatchReady",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "locker",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "coordinator",
"type": "address"
}
],
"name": "Configured",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "operationId",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "executor",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "requested",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "paid",
"type": "uint256"
}
],
"name": "ExecutionRewardPaid",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "units",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ethAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "bimoAmount",
"type": "uint256"
}
],
"name": "FinalPartialBatchReleased",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "Finalized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "slotId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "FissionDistributed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "firstSlot",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "slots",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "bimoReserved",
"type": "uint256"
}
],
"name": "FissionSlotsReserved",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "FreeInventoryBurned",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "FreeInventorySentToAirdropVault",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "FreeInventorySentToB",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "batchId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ethAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "bimoAmount",
"type": "uint256"
}
],
"name": "FullBatchReleased",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "minter",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "quantity",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "firstUnit",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "lpEth",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "operationsFee",
"type": "uint256"
}
],
"name": "Minted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "UnclaimedFissionFinalized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "UnexpectedEthSwept",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "UnusedOperationsReserveSwept",
"type": "event"
},
{
"inputs": [],
"name": "BATCH_BIMO",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "BATCH_ETH",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "BATCH_SIZE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FISSION_AMOUNT_PER_ADDRESS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "FISSION_AMOUNT_PER_UNIT",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LAUNCH_INVENTORY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LP_BIMO_PER_UNIT",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LP_PRICE_PER_UNIT",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_FISSION_RECIPIENTS_PER_CALL",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_MINTS_PER_TRANSACTION",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_MINTS_PER_WALLET",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_MINT_UNITS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MINTER_AMOUNT_PER_UNIT",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MINT_DURATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "PROJECT_RESERVE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TOTAL_SUPPLY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "activate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "active",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "addLiquidityExecutionReward",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "batchId",
"type": "uint256"
}
],
"name": "addLiquidityRewardPaid",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "airdropVault",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "availableFullBatches",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "availableLiquidityBatches",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "bSingleSigner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "bimo",
"outputs": [
{
"internalType": "contract IBimoToken",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "burnFreeInventory",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "buybackExecutionReward",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "locker_",
"type": "address"
},
{
"internalType": "address",
"name": "coordinator_",
"type": "address"
}
],
"name": "configure",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "coordinator",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "deployer",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "recipients",
"type": "address[]"
}
],
"name": "distributeFission",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "finalPartialBatchReleased",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "finalize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "finalizeUnclaimedFission",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "finalized",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fissionBimoDistributed",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fissionBimoFinalized",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fissionBimoReserved",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fissionExecutionRewardPerRecipient",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fissionFinalized",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fissionSlotsCreated",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fissionSlotsDistributed",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "freeInventory",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "freeInventoryFinalized",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "hook",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "locker",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "lpEthReserved",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint8",
"name": "quantity",
"type": "uint8"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "mintEnd",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "operationsFeePerUnit",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "operationsReserve",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingFissionBimo",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingLiquidityBimo",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "processedFullBatches",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "processedUnits",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "firstBatchId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "batchCount",
"type": "uint256"
}
],
"name": "releaseLiquidityBatches",
"outputs": [
{
"internalType": "uint256",
"name": "ethAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "bimoAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "units",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "sendFreeInventoryToAirdropVault",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "sendFreeInventoryToB",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "batchId",
"type": "uint256"
}
],
"name": "settleAddLiquidityExecutionReward",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "operationId",
"type": "bytes32"
}
],
"name": "settleBuybackExecutionReward",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "settleFinalPartialLiquidityExecutionReward",
"outputs": [],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"name": "sweepUnexpectedEth",
"outputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "sweepUnusedOperationsReserve",
"outputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalExecutionRewardsPaid",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalMintedUnits",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalOperationsFeesCollected",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "wallet",
"type": "address"
}
],
"name": "walletMints",
"outputs": [
{
"internalType": "uint256",
"name": "units",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {IBimoToken} from "./interfaces/IBimoToken.sol";
import {IBIMOExecutionCoordinator, ILaunchBurner} from "./interfaces/IBIMOV1.sol";
import {SafeTransfer} from "./utils/SafeTransfer.sol";
import {BIMOConstants} from "./BIMOConstants.sol";
/// @notice Immutable fixed-price BIMO sale, fission distribution, and V4 batch accounting vault.
contract BIMOImmutableLaunchVault {
using SafeTransfer for address;
uint256 public constant TOTAL_SUPPLY = BIMOConstants.TOTAL_SUPPLY;
uint256 public constant PROJECT_RESERVE = BIMOConstants.PROJECT_RESERVE;
uint256 public constant LAUNCH_INVENTORY = BIMOConstants.LAUNCH_INVENTORY;
uint256 public constant MAX_MINT_UNITS = BIMOConstants.MAX_MINT_UNITS;
uint256 public constant MAX_MINTS_PER_WALLET = BIMOConstants.MAX_MINTS_PER_WALLET;
uint8 public constant MAX_MINTS_PER_TRANSACTION = BIMOConstants.MAX_MINTS_PER_TRANSACTION;
uint256 public constant LP_PRICE_PER_UNIT = BIMOConstants.LP_PRICE_PER_UNIT;
uint256 public constant MINTER_AMOUNT_PER_UNIT = BIMOConstants.MINTER_AMOUNT_PER_UNIT;
uint256 public constant FISSION_AMOUNT_PER_UNIT = BIMOConstants.FISSION_AMOUNT_PER_UNIT;
uint256 public constant FISSION_AMOUNT_PER_ADDRESS = BIMOConstants.FISSION_AMOUNT_PER_ADDRESS;
uint256 public constant LP_BIMO_PER_UNIT = BIMOConstants.LP_BIMO_PER_UNIT;
uint256 public constant BATCH_SIZE = BIMOConstants.BATCH_SIZE;
uint256 public constant BATCH_ETH = BIMOConstants.BATCH_ETH;
uint256 public constant BATCH_BIMO = BIMOConstants.BATCH_BIMO;
uint256 public constant MINT_DURATION = BIMOConstants.MINT_DURATION;
uint256 public constant MAX_FISSION_RECIPIENTS_PER_CALL = 100;
IBimoToken public bimo;
address public bSingleSigner;
address public airdropVault;
address public hook;
address public deployer;
address public coordinator;
address public locker;
uint256 public mintEnd;
bool public active;
bool public finalized;
uint256 public totalMintedUnits;
uint256 public processedUnits;
uint256 public processedFullBatches;
uint256 public fissionSlotsCreated;
uint256 public fissionSlotsDistributed;
uint256 public fissionBimoReserved;
uint256 public fissionBimoDistributed;
uint256 public fissionBimoFinalized;
uint256 public lpEthReserved;
uint256 public operationsReserve;
uint256 public totalOperationsFeesCollected;
uint256 public totalExecutionRewardsPaid;
uint256 public operationsFeePerUnit;
uint256 public addLiquidityExecutionReward;
uint256 public fissionExecutionRewardPerRecipient;
uint256 public buybackExecutionReward;
uint256 private _entered;
mapping(address wallet => uint256 units) public walletMints;
mapping(uint256 batchId => bool) public addLiquidityRewardPaid;
mapping(bytes32 rewardId => bool) private _operationRewardPaid;
bool public finalPartialBatchReleased;
bool public fissionFinalized;
uint256 public freeInventoryFinalized;
error Unauthorized();
error Reentrancy();
error InvalidAddress();
error InvalidConfiguration();
error IncorrectPayment();
error InvalidQuantity();
error MintLimitExceeded();
error SoldOut();
error MintClosed();
error NotActive();
error InventoryNotFunded();
error InvalidFissionRecipient();
error FissionSlotsExceeded();
error FissionBatchTooLarge();
error FissionNotFinalized();
error FissionAlreadyFinalized();
error OperationAlreadyRewarded();
error NoFullBatchAvailable();
error OutOfOrderBatch();
error FinalPartialUnavailable();
error NotFinalizable();
error AlreadyFinalized();
error InsufficientFreeInventory();
error DirectEthDisabled();
event Configured(address indexed locker, address indexed coordinator);
event Activated(uint256 indexed mintEnd);
event Minted(
address indexed minter, uint256 quantity, uint256 firstUnit, uint256 lpEth, uint256 operationsFee
);
event BatchReady(uint256 indexed batchId, uint256 indexed units, uint256 ethAmount, uint256 bimoAmount);
event FissionSlotsReserved(uint256 indexed firstSlot, uint256 slots, uint256 bimoReserved);
event FissionDistributed(address indexed recipient, uint256 indexed slotId, uint256 amount);
event UnclaimedFissionFinalized(uint256 amount);
event ExecutionRewardPaid(
bytes32 indexed operationId, address indexed executor, uint256 requested, uint256 paid
);
event FullBatchReleased(uint256 indexed batchId, uint256 ethAmount, uint256 bimoAmount);
event FinalPartialBatchReleased(uint256 indexed units, uint256 ethAmount, uint256 bimoAmount);
event FreeInventoryBurned(uint256 amount);
event FreeInventorySentToAirdropVault(uint256 amount);
event FreeInventorySentToB(uint256 amount);
event UnusedOperationsReserveSwept(address indexed recipient, uint256 amount);
event Finalized();
event UnexpectedEthSwept(address indexed recipient, uint256 amount);
modifier onlyB() {
if (msg.sender != bSingleSigner) revert Unauthorized();
_;
}
modifier onlyCoordinator() {
if (msg.sender != coordinator) revert Unauthorized();
_;
}
modifier nonReentrant() {
if (_entered != 0) revert Reentrancy();
_entered = 1;
_;
_entered = 0;
}
constructor(
address bimo_,
address bSingleSigner_,
address airdropVault_,
address hook_,
address deployer_,
uint256 operationsFeePerUnit_,
uint256 addLiquidityExecutionReward_,
uint256 fissionExecutionRewardPerRecipient_,
uint256 buybackExecutionReward_
) {
if (
bimo_ == address(0) || bSingleSigner_ == address(0) || airdropVault_ == address(0)
|| hook_ == address(0) || deployer_ == address(0) || airdropVault_ == bSingleSigner_
|| airdropVault_.code.length == 0 || hook_.code.length == 0
) {
revert InvalidAddress();
}
bimo = IBimoToken(bimo_);
bSingleSigner = bSingleSigner_;
airdropVault = airdropVault_;
hook = hook_;
deployer = deployer_;
operationsFeePerUnit = operationsFeePerUnit_;
addLiquidityExecutionReward = addLiquidityExecutionReward_;
fissionExecutionRewardPerRecipient = fissionExecutionRewardPerRecipient_;
buybackExecutionReward = buybackExecutionReward_;
}
function configure(address locker_, address coordinator_) external {
if (msg.sender != deployer) revert Unauthorized();
if (active || locker != address(0) || coordinator != address(0)) revert InvalidConfiguration();
if (
locker_ == address(0) || coordinator_ == address(0) || locker_.code.length == 0
|| coordinator_.code.length == 0
) {
revert InvalidAddress();
}
IBIMOExecutionCoordinator coordinatorContract = IBIMOExecutionCoordinator(coordinator_);
if (coordinatorContract.executor() == airdropVault) revert InvalidAddress();
if (coordinatorContract.launch() != address(this) || coordinatorContract.locker() != locker_) {
revert InvalidConfiguration();
}
locker = locker_;
coordinator = coordinator_;
emit Configured(locker_, coordinator_);
}
function activate() external {
if (msg.sender != deployer) revert Unauthorized();
if (active || locker == address(0) || coordinator == address(0)) revert InvalidConfiguration();
if (bimo.balanceOf(address(this)) != LAUNCH_INVENTORY) revert InventoryNotFunded();
active = true;
mintEnd = block.timestamp + MINT_DURATION;
deployer = address(0);
emit Activated(mintEnd);
}
function mint(uint8 quantity) external payable nonReentrant {
if (!active) revert NotActive();
if (block.timestamp >= mintEnd) revert MintClosed();
if (quantity == 0 || quantity > MAX_MINTS_PER_TRANSACTION) revert InvalidQuantity();
if (walletMints[msg.sender] + quantity > MAX_MINTS_PER_WALLET) revert MintLimitExceeded();
if (totalMintedUnits + quantity > MAX_MINT_UNITS) revert SoldOut();
uint256 lpEth = uint256(quantity) * LP_PRICE_PER_UNIT;
uint256 operationsFee = uint256(quantity) * operationsFeePerUnit;
if (msg.value != lpEth + operationsFee) revert IncorrectPayment();
uint256 requiredBimo =
uint256(quantity) * (MINTER_AMOUNT_PER_UNIT + FISSION_AMOUNT_PER_UNIT + LP_BIMO_PER_UNIT);
if (bimo.balanceOf(address(this)) < requiredBimo) revert InventoryNotFunded();
uint256 firstUnit = totalMintedUnits + 1;
uint256 firstSlot = fissionSlotsCreated + 1;
uint256 previousFullBatches = totalMintedUnits / BATCH_SIZE;
walletMints[msg.sender] += quantity;
totalMintedUnits += quantity;
fissionSlotsCreated += uint256(quantity) * 2;
fissionBimoReserved += uint256(quantity) * FISSION_AMOUNT_PER_UNIT;
lpEthReserved += lpEth;
operationsReserve += operationsFee;
totalOperationsFeesCollected += operationsFee;
address(bimo).safeTransfer(msg.sender, uint256(quantity) * MINTER_AMOUNT_PER_UNIT);
emit Minted(msg.sender, quantity, firstUnit, lpEth, operationsFee);
emit FissionSlotsReserved(
firstSlot, uint256(quantity) * 2, uint256(quantity) * FISSION_AMOUNT_PER_UNIT
);
uint256 newFullBatches = totalMintedUnits / BATCH_SIZE;
for (uint256 batchId = previousFullBatches + 1; batchId <= newFullBatches; ++batchId) {
emit BatchReady(batchId, BATCH_SIZE, BATCH_ETH, BATCH_BIMO);
}
}
function distributeFission(address[] calldata recipients) external onlyCoordinator nonReentrant {
if (fissionFinalized) revert FissionAlreadyFinalized();
uint256 count = recipients.length;
if (count == 0 || count > MAX_FISSION_RECIPIENTS_PER_CALL) revert FissionBatchTooLarge();
if (fissionSlotsDistributed + count > fissionSlotsCreated) revert FissionSlotsExceeded();
for (uint256 i; i < count; ++i) {
if (recipients[i] == address(0)) revert InvalidFissionRecipient();
}
uint256 firstSlot = fissionSlotsDistributed + 1;
fissionSlotsDistributed += count;
uint256 distributed = count * FISSION_AMOUNT_PER_ADDRESS;
fissionBimoDistributed += distributed;
for (uint256 i; i < count; ++i) {
address recipient = recipients[i];
address(bimo).safeTransfer(recipient, FISSION_AMOUNT_PER_ADDRESS);
emit FissionDistributed(recipient, firstSlot + i, FISSION_AMOUNT_PER_ADDRESS);
}
_payExecutionReward(
keccak256(abi.encodePacked("FISSION", firstSlot, count)),
fissionExecutionRewardPerRecipient * count
);
}
function availableFullBatches() public view returns (uint256) {
return totalMintedUnits / BATCH_SIZE - processedFullBatches;
}
function availableLiquidityBatches() public view returns (uint256) {
uint256 fullBatches = availableFullBatches();
if (fullBatches != 0) return fullBatches;
if ((block.timestamp < mintEnd && totalMintedUnits != MAX_MINT_UNITS) || finalPartialBatchReleased) {
return 0;
}
return totalMintedUnits > processedUnits ? 1 : 0;
}
function pendingFissionBimo() public view returns (uint256) {
return fissionBimoReserved - fissionBimoDistributed - fissionBimoFinalized;
}
function pendingLiquidityBimo() public view returns (uint256) {
return (totalMintedUnits - processedUnits) * LP_BIMO_PER_UNIT;
}
function freeInventory() public view returns (uint256) {
uint256 balance = bimo.balanceOf(address(this));
uint256 reserved = pendingFissionBimo() + pendingLiquidityBimo();
return balance > reserved ? balance - reserved : 0;
}
function releaseLiquidityBatches(uint256 firstBatchId, uint256 batchCount)
external
onlyCoordinator
nonReentrant
returns (uint256 ethAmount, uint256 bimoAmount, uint256 units)
{
if (firstBatchId != processedFullBatches + 1) revert OutOfOrderBatch();
uint256 fullBatches = availableFullBatches();
if (fullBatches != 0) {
if (batchCount == 0 || batchCount > fullBatches) revert NoFullBatchAvailable();
units = batchCount * BATCH_SIZE;
processedFullBatches += batchCount;
processedUnits += units;
ethAmount = batchCount * BATCH_ETH;
bimoAmount = batchCount * BATCH_BIMO;
lpEthReserved -= ethAmount;
_sendEth(locker, ethAmount);
address(bimo).safeTransfer(locker, bimoAmount);
emit FullBatchReleased(firstBatchId, ethAmount, bimoAmount);
return (ethAmount, bimoAmount, units);
}
if (batchCount != 1) revert FinalPartialUnavailable();
if (block.timestamp < mintEnd && totalMintedUnits != MAX_MINT_UNITS) revert MintClosed();
if (finalPartialBatchReleased) revert FinalPartialUnavailable();
units = totalMintedUnits - processedUnits;
if (units == 0 || units >= BATCH_SIZE) revert FinalPartialUnavailable();
processedUnits += units;
finalPartialBatchReleased = true;
ethAmount = units * LP_PRICE_PER_UNIT;
bimoAmount = units * LP_BIMO_PER_UNIT;
lpEthReserved -= ethAmount;
_sendEth(locker, ethAmount);
address(bimo).safeTransfer(locker, bimoAmount);
emit FinalPartialBatchReleased(units, ethAmount, bimoAmount);
}
function settleAddLiquidityExecutionReward(uint256 batchId) external onlyCoordinator nonReentrant {
uint256 finalPartialBatchId = totalMintedUnits / BATCH_SIZE + 1;
bool releasedFullBatch = batchId != 0 && batchId <= processedFullBatches;
bool releasedFinalPartialBatch =
finalPartialBatchReleased && batchId == finalPartialBatchId && totalMintedUnits % BATCH_SIZE != 0;
if ((!releasedFullBatch && !releasedFinalPartialBatch) || addLiquidityRewardPaid[batchId]) {
revert OperationAlreadyRewarded();
}
addLiquidityRewardPaid[batchId] = true;
_payExecutionReward(
keccak256(abi.encodePacked("ADD_LIQUIDITY", batchId)), addLiquidityExecutionReward
);
}
function settleFinalPartialLiquidityExecutionReward() external pure {
revert OperationAlreadyRewarded();
}
function settleBuybackExecutionReward(bytes32 operationId) external onlyCoordinator nonReentrant {
_payExecutionReward(operationId, buybackExecutionReward);
}
function burnFreeInventory(uint256 amount) external onlyB nonReentrant {
_consumeFreeInventory(amount);
address(bimo).safeTransfer(locker, amount);
ILaunchBurner(locker).burnLaunchBimo(amount);
emit FreeInventoryBurned(amount);
}
function sendFreeInventoryToAirdropVault(uint256 amount) external onlyB nonReentrant {
if (IBIMOExecutionCoordinator(coordinator).executor() == airdropVault) {
revert InvalidConfiguration();
}
_consumeFreeInventory(amount);
address(bimo).safeTransfer(airdropVault, amount);
emit FreeInventorySentToAirdropVault(amount);
}
function sendFreeInventoryToB(uint256 amount) external onlyB nonReentrant {
_consumeFreeInventory(amount);
address(bimo).safeTransfer(bSingleSigner, amount);
emit FreeInventorySentToB(amount);
}
function sweepUnusedOperationsReserve() external onlyB nonReentrant returns (uint256 amount) {
if (block.timestamp < mintEnd && totalMintedUnits != MAX_MINT_UNITS) revert NotFinalizable();
if (pendingLiquidityBimo() != 0 || pendingFissionBimo() != 0) revert NotFinalizable();
amount = operationsReserve;
if (amount == 0) revert InsufficientFreeInventory();
operationsReserve = 0;
_sendEth(bSingleSigner, amount);
emit UnusedOperationsReserveSwept(bSingleSigner, amount);
}
function finalizeUnclaimedFission() external onlyB nonReentrant {
if (fissionFinalized) revert FissionAlreadyFinalized();
if (block.timestamp < mintEnd && totalMintedUnits != MAX_MINT_UNITS) revert MintClosed();
uint256 amount = fissionBimoReserved - fissionBimoDistributed;
fissionFinalized = true;
fissionBimoFinalized = amount;
if (amount != 0) bimo.burn(amount);
emit UnclaimedFissionFinalized(amount);
}
function finalize() external onlyB nonReentrant {
if (finalized) revert AlreadyFinalized();
if (block.timestamp < mintEnd && totalMintedUnits != MAX_MINT_UNITS) revert NotFinalizable();
if (
pendingLiquidityBimo() != 0 || pendingFissionBimo() != 0 || freeInventory() != 0
|| operationsReserve != 0 || processedUnits != totalMintedUnits
) revert NotFinalizable();
finalized = true;
emit Finalized();
}
function sweepUnexpectedEth(address recipient) external onlyB nonReentrant returns (uint256 amount) {
if (recipient != bSingleSigner) revert InvalidAddress();
uint256 accounted = lpEthReserved + operationsReserve;
if (address(this).balance <= accounted) return 0;
amount = address(this).balance - accounted;
_sendEth(recipient, amount);
emit UnexpectedEthSwept(recipient, amount);
}
function _sendEth(address recipient, uint256 amount) private {
(bool sent,) = recipient.call{value: amount}("");
if (!sent) revert InvalidConfiguration();
}
function _payExecutionReward(bytes32 operationId, uint256 requested) private {
if (_operationRewardPaid[operationId]) revert OperationAlreadyRewarded();
_operationRewardPaid[operationId] = true;
uint256 paid = requested > operationsReserve ? operationsReserve : requested;
if (paid != 0) {
operationsReserve -= paid;
totalExecutionRewardsPaid += paid;
(bool sent,) = IBIMOExecutionCoordinator(coordinator).executor().call{value: paid}("");
if (!sent) revert InvalidConfiguration();
}
emit ExecutionRewardPaid(
operationId, IBIMOExecutionCoordinator(coordinator).executor(), requested, paid
);
}
function _consumeFreeInventory(uint256 amount) private {
if (block.timestamp < mintEnd && totalMintedUnits != MAX_MINT_UNITS) {
revert NotFinalizable();
}
if (amount == 0 || amount > freeInventory()) revert InsufficientFreeInventory();
freeInventoryFinalized += amount;
}
receive() external payable {
revert DirectEthDisabled();
}
}
Chain explorer3218msChain node72ms