feat(voting): BSC BEP20 CL8Y ledger + EVM wallet voting (core electorate) #4
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
BSC is core to the voting electorate, not an optional extra. A majority of CL8Y holders are on BNB Smart Chain (BEP-20), not Terra Classic CW20. Shipping cl8y-dex-terraclassic#509 / cl8y-dex-terraclassic#510 / cl8y-dex-terraclassic#511 as Terra-only would exclude most tokenholders from registration, proposal weight, and ballots.
Extend the offchain snapshot-voting bundle so that:
balanceOfat registration + Transfer logs forward — same “no archive node” model as cl8y-dex-terraclassic#509).operator-votingaccepts EVM wallet signatures (EIP-191personal_sign) for register / propose / vote, and freezes vote power from both the Terra CW20 ledger and the BSC BEP-20 ledger./voteflows.No new Solidity or CosmWasm contracts. Frontend + Postgres + indexer +
operator-votingonly.BEP-20 CL8Y (canonical BSC):
0x8F452a1fdd388A45e1080992eFF051b4dd9048d2(CL8Y_v2, 18 decimals) — same asset brand as Terra CW20terra16wtml…hpax3. Configurable via env (BSC_CL8Y_TOKEN_ADDRESS).Terra CW20 (unchanged, cl8y-dex-terraclassic#509):
terra16wtml2q66g82fdkx66tap0qjkahqwp4lwq3ngtygacg5q0kzycgqvhpax3.This issue is the cross-chain / EVM work item. It does not replace cl8y-dex-terraclassic#509–cl8y-dex-terraclassic#511; those issues must include BSC in their scope (see comments on each).
Bundle
operator-voting— Cosmos ADR-36 and EVM EIP-191 sigs; snapshot = Terra height plus BSC block; blacklist includes0xaddressesWhy this is needed
cl8y-dex-terraclassic#509–cl8y-dex-terraclassic#511 currently assume a Terra Classic wallet + CW20
Balance+ wasm transfer events. That is correct for the DEX’s home chain and for fee-discountcl8y_token, but it is not the majority CL8Y holder set.Without BSC:
Venus
eth_callonBSC_RPC_URLS(cl8y-dex-terraclassic#571) already proves the indexer can talk to BSC JSON-RPC. That path is oracle-only and must not be overloaded. Voting needs a separate BEP-20 ledger + EVM auth plane.Current codebase
indexer/src/indexer/venus_vfdusd.rs+config.bsc_rpc_urls(BSC_RPC_URLS) — Venus vFDUSDeth_callonly. Noeth_getLogs, no ERC-20balanceOf, no Transfer parserVITE_*BSC RPC, no BscScan from the dApp. Wallet provider connect for signing is a new surfacefrontend-dapp/src/services/terraclassic/wallet.ts). WalletConnect is EIP-155 Cosmos pairing (cl8y-dex-terraclassic#519 / cl8y-dex-terraclassic#554 / cl8y-dex-terraclassic#566), not BSChttps://terms.cl8y.com/sign/evm(cl8y-dex-terraclassic#517 clickwrap) — external redirect, not in-app MetaMask; do not reuse as voting authoperator-voting/votesignArbitraryConstraints / guardrails
balanceOf(wallet)at currenteth_blockNumber. History afterward = Transfer logs for the registered set only (mirror cl8y-dex-terraclassic#509).balanceOffor configuredBSC_CL8Y_TOKEN_ADDRESS(default0x8F452a1fdd388A45e1080992eFF051b4dd9048d2). Ignore other BEP-20s and lookalike tickers.NUMERIC— same as CW20; no float.fromortois a registered EVM address (plus the registered counterparty). Do not ingest the full CL8Y holder universe.BSC_RPC_URLStransport, not the Venus module. New indexer module (e.g.bsc_cl8y_ledger.rs). EmptyBSC_RPC_URLSskips live BSC (CI/LocalTerra) the same way cl8y-dex-terraclassic#571 does. Never log RPC URLs/keys. Soft-fail RPC must not invent balances.eth_call/eth_getLogs. Injected/WC provider is only for connect +personal_sign.terra1…registration and a0x…registration are distinct voters unless product later adds explicit linking. Do not silently merge by heuristic.VOTING_BLACKLIST_ADDRESSES) must accept normalized0x(EIP-55 checksum optional; compare case-insensitive) and Terra bech32.venus_vfdusd_rates.trader_positions, or PancakeSwap LP as vote weight.Relevant files
Indexer / BSC I/O
indexer/src/config.rs(bsc_rpc_urls)indexer/src/indexer/venus_vfdusd.rs(RPC failover /eth_callpattern — do not overload)indexer/src/startup.rs,indexer/src/lcd/mod.rs(Terra live balance analogue)indexer/migrations/,docs/indexer-invariants.mdbalanceOfregistration ingest + BSC height/block cursoroperator-voting (cl8y-dex-terraclassic#510)
ecrecoveroverkeccak256("\x19Ethereum Signed Message:\n" + len + message)), chain-id / domain separation, EVM address normalizevoting_bsc_cl8y_balance_at(wallet, block)beside Terravoting_cl8y_balance_atFrontend (cl8y-dex-terraclassic#511)
frontend-dapp/src/services/terraclassic/wallet.ts,hooks/useWallet.ts, WalletConnect pairing stores (cl8y-dex-terraclassic#554)frontend-dapp/src/utils/legalClickwrap.ts(Legal EVM portal is not voting)personal_signhelper;/votecopy that Terra or BSC holders can registerAGENTS_FRONTEND_WALLETCONNECT_MOBILE.md,AGENTS_FRONTEND_COPY_COGNITIVE_LOAD.md,AGENTS_INDEXER_VENUS_VFDUSD.md(RPC hygiene)Env / deploy
BSC_RPC_URLS(existing),BSC_CL8Y_TOKEN_ADDRESS, Coolify indexer +operator-voting+ frontend examplesVITE_*must not include BSC RPC URLsRecommended direction
Indexer (extends #509)
voting_registrationsgainschain(terra|bsc) +address;cl8y_bep20_transfers(bsc_block, tx_hash, log_index, from, to, amount);cl8y_bsc_balancescheckpoints forbalance(wallet, bsc_block)whenblock >= registered_at_block.eth_blockNumber+eth_callbalanceOf(address)on pinned CL8Y; persist; no historicaleth_getLogsbackfill unless explicitly designed (default no backfill, same as cl8y-dex-terraclassic#509).eth_getLogsfor Transfer topic0xddf252ad…on the pinned token; filter to registered set; handle mint/burn (from/tozero address).indexer_state.operator-voting (extends #510)
chain/ recovered address.{ terra_height, bsc_block, created_at }.Frontend (extends #511)
eip155:56).Acceptance criteria
balanceOf+ current BSC block; no archive/debug_tracerequirement.balance(evm, B)forB >= registered_at_blockis reconstructible from the ledger; property/integration tested with fixtures (wiremock / Anvil — not live mainnet).operator-votingaccepts EIP-191 register / propose / vote from the recovered0xaddress; Terra ADR-36 path still works.0xcannot vote or propose.VITE_*BSC RPC; no Venus poller reuse; docs/invariants/Coolify env updated.Test plan (all paths)
from/to.v/ replayed Terra payload.balanceOfat block N; row matches.BSC_RPC_URLSskips BSC ledger when feature optional in CI; production voting compose requires it.Test plan — attack, hack & abuse vectors
BSC_RPC_URLSremains env-only (existing I389-18 class); do not take RPC URL from client.0xabc…vs0xAbC…must be one wallet; blacklist bypass via case must fail.Verification criteria
operator-votingtests for EIP-191 + mixed Terra/EVM blacklist + dual snapshot fields.docs/indexer-invariants.md+ Coolify env; skill notes that voting BSC I/O ≠ Venus.Labels
architecturebackendfrontendindexerenhancementsecurityproductUXPriority
P1 — core electorate. Majority of CL8Y is BEP-20 on BSC.
marked as related to cl8y-dex-terraclassic#509
marked as related to cl8y-dex-terraclassic#510
marked as related to cl8y-dex-terraclassic#511
mentioned in issue cl8y-dex-terraclassic#509
mentioned in issue cl8y-dex-terraclassic#510
mentioned in issue cl8y-dex-terraclassic#511
moved from cl8y-dex-terraclassic#588
mentioned in issue #6
mentioned in issue #5
mentioned in issue #1
mentioned in issue #2
mentioned in issue #3
changed the description
Repo split + updated links (2026-08-25)
Moved from
cl8y-dex-terraclassic#588to https://gitlab.com/PlasticDigits/voting/-/issues/4BSC remains core electorate. EVM connect should follow the Bridge stack (#6), not a new wallet kit. Legal still applies to EVM wallets (#5).
/votementioned in issue cl8y-dex-terraclassic#588
mentioned in issue cl8y-dex-terraclassic#637
mentioned in commit
8d11152cfementioned in commit
b32b56660dmentioned in merge request !18
Implemented on feat/voting-bundle. MR: https://gitlab.com/PlasticDigits/voting/-/merge_requests/1
In-tree: ledger/ (CW20 + BEP-20), operator-voting/, frontend/ (/vote + Legal + ported wallets).
Docs: docs/LEDGER_INVARIANTS.md, docs/OPERATOR_VOTING.md, docs/FRONTEND.md.
mentioned in commit
8fe45a1974mentioned in issue #7
Merge verify (!18 → main, no conflicts). BSC ledger + EIP-191 + dual snapshot + Bridge-style EVM connect are on main. No
VITE_*BSC RPC for balances.Still open after merge (tracked in #7):
mentioned in issue #12
mentioned in issue #13
mentioned in issue #16