From 5861c412c8c12403b2b8553d6a5615d916ed4232 Mon Sep 17 00:00:00 2001 From: Hossein Zoda Date: Thu, 27 Aug 2026 09:39:57 +0000 Subject: [PATCH] ido: rebake preinit for the zero-remainder oToken genesis libriften 00ff654 relaxed ido/preinit.cash's `offeredTokenTotalSupply > fundingOTokenAmount` to `>=`, so a token can be minted with its whole supply committed to the IDO. At a zero remainder the oToken authbase cannot hold a zero-amount token output, so it carries an immutable NFT with the OTOKEN_AUTHBASE_NFT_COMMITMENT ("BCMR") marker instead; preinit grows 1419 -> 1433 bytes. - Swap the baked IDO_PREINIT_CONTRACT hex to the new bytecode from templates/ido.json (contracts.IDOPreInit). The only bytecode changes are a069 -> a269 and the output#0 commitment check becoming a branch on the remainder; without the swap no new preinit's rebuilt p2sh32 would match and no IDO would be admitted. - Relax the announcement-validation mirror of that require from `<=` to `<`, so a whole-supply genesis is no longer marked invalid. The state machine never reads output#0's commitment or amount, and build_preinit_bytecode bakes no contract length (the size feeds only the unlock bytecode, which the indexer does not build), so nothing else moves. The other 14 baked contracts still match the current templates, and the schema and announcement format are unchanged, so IDO_DB_VERSION stays at 5. Co-Authored-By: Claude Opus 5 (1M context) --- src/db/ido/mod.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/db/ido/mod.rs b/src/db/ido/mod.rs index 24b596a..77388a8 100644 --- a/src/db/ido/mod.rs +++ b/src/db/ido/mod.rs @@ -117,7 +117,7 @@ static IDO_POSTLAUNCH_CONTRACT: LazyLock> = LazyLock::new(|| { hex::decode("0401207f7500895e79009c63c0009dc0c9009e69c0cdc0c788c0ccc0c6a269c0d1c0ce88c0d3c0d09dc0d2c0cf88520052807e5e7a7ec0c851c88851c9589d7651cd8851cc51c6a26951d151ce8851d351d09d7652cd8852d10088c0c852c88852c9599d53cd8853cc52c6a26953d152ce8853d352d09d54d10088c4559d006576c39f766b6376ce00876476ce008a5d7987916968768b77686c91666d6d6d6d6d6d6d7551675e79519c63c0009dc0c9009d57790087c0cdc0c788c0d1c0ce88c0d3c0d09dc0d2c0cf88c0c853c88853c9539d53cd53c78853cc53c6a26953d153ce8853d353d09d0120c0cfc0ce7eaa7e5e7a7e000000546576ce00876476ce008a0112798791696876c75579876355796376ce0111798763537978d093547a757c6b7c6b7c6c6c6ec6937b757c6776ce0088527978c693537a757c6b7c6c686776ce5e798763527978d093537a757c6b7c6c6776ce0111798763537978d093547a757c6b7c6b7c6c6c6776ce008868686ec6937b757c686776ce008868768b7776c3a266c0ccc0c6537a93a269c0ccc0c6577a8193a269c0c851c88851c9519d51cd51c78851cc51c6a26951d0537a937600a06351d15f798851d378a26951d200886751d1008868c0c852c88852c9529d52cd52c788547a6352cc52c6547993a26952d100886752cc52c6a26952d05379937600a06352d15c798852d378a26952d200886752d100886875686d6d6d6d6d6d6d6d7551675e7a529dc0009dc0c9009d5979827701209d5779008754ce5d7a8854cf517f755f845588c0c851c88851c9519d54cf5f7f77587f75817600a06351d078a26951ce5d79886851cf0088c0c852c88852c9529d54cf577f77587f75817600a06352796352c678a2696752d078a26952ce5b7988686852cf0088c0c853c88853c9539d53ce5e7988000054cf517f756084010087635d7981547994765d79950400e1f505967653d0a06353d07768765d79950500e87648179654cf01177f77587f758194760500e8764817955e79967800a07800a09a6378567a757c6b7c6b7c6b7c6b7c6c6c6c6c765379a16376557a757c6b7c6b7c6b7c6c6c6c675279557a757c6b7c6b7c6b7c6c6c6c68686d6d6852d052c656796352c67b75770068c0c651c6939353c6937c53799451d053d093537994012001127a7e0113797e5c7900a26952795d7a950400e1f50596537a7894567900a0567900a09a6359796300cc5779a26900d10113798800d356799d00d200884ce7c0c776517f77587f527f527f527f587f587f01207f77517f7501008791567a81567a81567a81567a81567a81567a81c0cec0d188c0c6c0ccc0d0c0d3557955795c7a63c0d0567a757c6b7c6b7c6b7c6b7c6c6c6c6cc0d3557a757c6b7c6b7c6b7c6c6c6cc0c6547a757c6b7c6b7c6c6cc0cc537a757c6b7c6c56797b757c5779776855795579949003a08601765a9552795e7a9578938c7c967b5c7a955279938c7b965b795279937b5279935b7aa269013f7858807e5c7a597f777ec0cd88567a7c947651a269547951a269567a597a94547993567a547993957c7b94537a93729395a17777205c797e4cab78cf7bce7eaac0c776517f77587f75817600a26978013f7f77517f75010087915379557987637663c0d3c0d05379949dc0ccc0c6a26967c0ccc0c6537994a269c0d3c0d09d68c0cec0d188c0cd597f77527f75768100a269013f0058807e787e54795b7f777ec0cd78886d675279011f7f7701207f7554797888527900a063c0cd012057797e0778cf7bce7eaa877e887863c0d1c0ce88c0d353799d67c0cc5379a269686875686d6d75517eaa07ca537f7776aa20787e0f8802e6007f7b63756777680089008a7e0800000000000000000200007e0200007e5f797e0800000000000000007e0800000000000000007e2000000000000000000000000000000000000000000000000000000000000000007e01007e00cd013f52797e01757e53797e8851d1008851cd016a886d756700d10111798800d357799d00d2008851d10113798851d356799d51d200884cbac0c8c08bc888c08bc9c0c98b9dc08bc7517f77587f527f527f527f587f587f75557a81557a81557a81557a81557a81557a81c0cec0d188c0c6c0cc9dc08bcec08bd188c08bc6c08bcc9dc0d0c0d3949003a08601765a955279587a9578938c7c967b567a955279938c7b9655795279937b527993557aa269c0cdc0c788013e7858807ec08bc7597f777ec08bcd88c0d37c947651a269c08bd351a269c0d0557a94547993c08bd0547993957c7b94537a93c08bd3537a9395a1205c797e4ca678cf7bce7eaac0c8c08bc888c08bc9c0c98b9dc08bc776517f77587f75817600a269708763c0d3c0d05279949dc08bd3c08bd09dc0cec0d188c0c6c0cc9dc08bcec08bd188c08bc6c08bcc9dc0cdc0c788c08bcd597f77527f75768100a269013e0058807e787e53795b7f777ec08bcd78886d6778011f7f7701207f75537978887800a063c0cd012056797e0778cf7bce7eaa877e88c0d1c0ce88c0d352799d6875686d6d517eaa00cd07ca537f7776aa2052797e0f8802b9007f7b63756777680089008a7e880800000000000000000200007e0200007e5e797e0800000000000000007e0800000000000000007e2000000000000000000000000000000000000000000000000000000000000000007e013e787e0e75c08c76c8c0c888c0c97cc98b9c7e51cd78886d75686700d1008800cd016a8851d1008851cd016a8868537900a063527952cd8852d35479a26952d10113798852d200886752cd016a8852d10088687600a063527953cd8859796353cc78a26953d100886753d3789d53d10111798853d20088686753cd016a8853d100886801205e7a7e01137a7e54cd88597a6354cc5579537993a26954d100886754cc5579a2697800a06354d35279a26954d15f798854d200886754d100886868556576c49f766b6376d100876476d1008a7654ce008a87916976c0ce008a8791697568768b77686c91666d6d6d6d6d6d6d6d6d75516868").unwrap() }); static IDO_PREINIT_CONTRACT: LazyLock> = LazyLock::new(|| { - hex::decode("0902aa207caa7e01877e00890902a9147ca97e01877e5189c0519dc0c800c88800c9529dc0c852c88852c9539dc0c853c88853c9549dc0c854c88854c9559dc0c855c88855c9569dc0c856c88856c9579d5c79009e63c0c858c88858c9599d67c0c858c88858c9599d68c0c857c88857c9589d597981009c5d79009c9b5b7981009c9b63c0d1008852cd00c78852d1008853cd52c78853d1008854cd53c78854d1008855cd54c78855d1008856cd55c78856d1008857cd56c78857d100885c79009e6359cd58c78859cc58c6a26959d158ce8859d358d09d59d258cf8867597981009e5c79009e9a6459cd58c78859d10088686858cd57c78858d100880302010054797ec1014e7f775b7981009c6301005f79009e63015177685e79009c6300cd53798800d10088760251207e5e797e01207e5d797e52797e7b757c67c0c859c88859c9009d00cd016a8800d100885acd5c79885ad1c0c8885ad3009d5ad20100885bd10088c45c9d760200207e5e797e01207ec0c87e52797e7b757c6875675e79009c635d79009c6300cd52798800d10088030051205d797e01207e5c797e787e7767c0c859c88859c9009d53795579950400e1f50596547978935479789455795279a06901205f797e5c797e5b797e008a5c798277009c63012060797e5b797e518a776800cd788800d1c0c88800d352799d00d2008859cd56798859d1c0c88859d353799d59d2008858c7827758c77853947f77527f758158c7527953945279947f77787f7576827700a06376517f75768176014b9f788b547982779f9a635279788b7f77537a757c6b7c6c5279517f757b757c6878016a8764016a537a757c6b7c6c686d67016a77685acd78885ad100885bd10088c45c9d035100200114797e01207e0113797e58797e587a757c6b7c6b7c6b7c6b7c6b7c6b7c6c6c6c6c6c6c6d6d6d7568675d79009c6300cd52798800d10088035151205d797e01207e5c797e787e7767c0c859c88859c9009d00cd016a8800d100885acd5279885ad1c0c8885ad3009d5ad201ff885bd10088c45c9d03510020c0c87e01207e5c797e787e77686868c15a7f75787e008ac0cd886d67c0c859c88859c95a9d55ca827755ca7853947f77527f758155ca527953945279947f77787f75012301205e797e5c797e5a797e008a7e5b798277009c63011701205f797e5a797e518a7e776800cdc15a7f7552797e53797e008a8800d1008800ca827700ca7853947f77527f75815178529302ff00a063755367785293014ba0637552686800ca537953945379945279947f77030200005c797e787e008a51cd8851d1008852ca827752ca7853947f77527f75815178529302ff00a063755367785293014ba0637552686852ca537953945379945279947f770302000060797e7853795a937f757e01207e01ff0118797eaa7e785379012b937f777e008a52cd8852d1008853ca827753ca7853947f77527f75815178529302ff00a063755367785293014ba0637552686853ca537953945379945279947f77030200000114797e787e008a53cd8853d1008854ca827754ca7853947f77527f75815178529302ff00a063755367785293014ba0637552686854ca537953945379945279947f77030200000118797e787e008a54cd8854d1008857c7827757c77853947f77527f75815178529302ff00a063755367785293014ba0637552686857c7537953945379945279947f7755cd03020000011d797e52797e8855d1008803020000011c797e56cd8856cc58c6a26956d158ce8856d3011a799d56d2008856ca827756ca7853947f77527f758156ca527953945279947f77787f7557cdc15a7f7501207e01000127797eaa7e52797e008a8857cc59c6a26957d159ce8857d359d09d57d259cf88525752807e011f797e58cd8858d158ce8858d358d0011e79949d58d200886d6d6d6d6d6d6d6d6d6d6d6d6d75686d6d6d6d6d6d7551").unwrap() + hex::decode("0902aa207caa7e01877e00890902a9147ca97e01877e5189c0519dc0c800c88800c9529dc0c852c88852c9539dc0c853c88853c9549dc0c854c88854c9559dc0c855c88855c9569dc0c856c88856c9579d5c79009e63c0c858c88858c9599d67c0c858c88858c9599d68c0c857c88857c9589d597981009c5d79009c9b5b7981009c9b63c0d1008852cd00c78852d1008853cd52c78853d1008854cd53c78854d1008855cd54c78855d1008856cd55c78856d1008857cd56c78857d100885c79009e6359cd58c78859cc58c6a26959d158ce8859d358d09d59d258cf8867597981009e5c79009e9a6459cd58c78859d10088686858cd57c78858d100880302010054797ec1014e7f775b7981009c6301005f79009e63015177685e79009c6300cd53798800d10088760251207e5e797e01207e5d797e52797e7b757c67c0c859c88859c9009d00cd016a8800d100885acd5c79885ad1c0c8885ad3009d5ad20100885bd10088c45c9d760200207e5e797e01207ec0c87e52797e7b757c6875675e79009c635d79009c6300cd52798800d10088030051205d797e01207e5c797e787e7767c0c859c88859c9009d53795579950400e1f50596547978935479789455795279a26901205f797e5c797e5b797e008a5c798277009c63012060797e5b797e518a776800cd788800d1c0c88800d352799d78009c6300d20442434d52886700d200886859cd56798859d1c0c88859d353799d59d2008858c7827758c77853947f77527f758158c7527953945279947f77787f7576827700a06376517f75768176014b9f788b547982779f9a635279788b7f77537a757c6b7c6c5279517f757b757c6878016a8764016a537a757c6b7c6c686d67016a77685acd78885ad100885bd10088c45c9d035100200114797e01207e0113797e58797e587a757c6b7c6b7c6b7c6b7c6b7c6b7c6c6c6c6c6c6c6d6d6d7568675d79009c6300cd52798800d10088035151205d797e01207e5c797e787e7767c0c859c88859c9009d00cd016a8800d100885acd5279885ad1c0c8885ad3009d5ad201ff885bd10088c45c9d03510020c0c87e01207e5c797e787e77686868c15a7f75787e008ac0cd886d67c0c859c88859c95a9d55ca827755ca7853947f77527f758155ca527953945279947f77787f75012301205e797e5c797e5a797e008a7e5b798277009c63011701205f797e5a797e518a7e776800cdc15a7f7552797e53797e008a8800d1008800ca827700ca7853947f77527f75815178529302ff00a063755367785293014ba0637552686800ca537953945379945279947f77030200005c797e787e008a51cd8851d1008852ca827752ca7853947f77527f75815178529302ff00a063755367785293014ba0637552686852ca537953945379945279947f770302000060797e7853795a937f757e01207e01ff0118797eaa7e785379012b937f777e008a52cd8852d1008853ca827753ca7853947f77527f75815178529302ff00a063755367785293014ba0637552686853ca537953945379945279947f77030200000114797e787e008a53cd8853d1008854ca827754ca7853947f77527f75815178529302ff00a063755367785293014ba0637552686854ca537953945379945279947f77030200000118797e787e008a54cd8854d1008857c7827757c77853947f77527f75815178529302ff00a063755367785293014ba0637552686857c7537953945379945279947f7755cd03020000011d797e52797e8855d1008803020000011c797e56cd8856cc58c6a26956d158ce8856d3011a799d56d2008856ca827756ca7853947f77527f758156ca527953945279947f77787f7557cdc15a7f7501207e01000127797eaa7e52797e008a8857cc59c6a26957d159ce8857d359d09d57d259cf88525752807e011f797e58cd8858d158ce8858d358d0011e79949d58d200886d6d6d6d6d6d6d6d6d6d6d6d6d75686d6d6d6d6d6d7551").unwrap() }); static STORAGE_CONTRACT: LazyLock> = @@ -1547,15 +1547,23 @@ fn parse_ido_preinit_tx_params( // all-zero on-chain sentinel): a native IDO takes payment via // the offering's XWNT path and its permanent pool is a // single-UTXO tokenbch pool. No rejection here. + // The genesis transaction mints the whole supply: the funded + // amount (offeredTokenAmount + the permanent liquidity reserve) + // plus the remainder held by the oToken authbase. Equal is + // allowed — the authbase then carries no tokens and holds an + // immutable NFT with the OTOKEN_AUTHBASE_NFT_COMMITMENT ("BCMR") + // marker instead, since a token output cannot carry zero + // fungible tokens and no NFT. Below the funded amount the + // preinit contract rejects the genesis step. if !offered_token_is_in_supply { let permanentLiquidityOTokenReserve: Integer = &preinit_parameters .offeredTokenAmount * &preinit_parameters.permanentLiquidityShareNumerator / &PERMANENT_LIQUIDITY_SHARE_DENOMINATOR.clone(); if preinit_parameters.offeredTokenTotalSupply - <= &preinit_parameters.offeredTokenAmount + &permanentLiquidityOTokenReserve + < &preinit_parameters.offeredTokenAmount + &permanentLiquidityOTokenReserve { - invalid_ido_reasons.push(anyhow::anyhow!("ido parse, not a valid ido, preinit_parameters.offeredTokenTotalSupply <= preinit_parameters.offeredTokenAmount + permanentLiquidityOTokenReserve")); + invalid_ido_reasons.push(anyhow::anyhow!("ido parse, not a valid ido, preinit_parameters.offeredTokenTotalSupply < preinit_parameters.offeredTokenAmount + permanentLiquidityOTokenReserve")); is_valid_ido = false; } }